With this project, the vast majority of my time has been just trying to marry a number of diverse technologies together and get them to play nicely with each other in the Java EE ecosystem.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/PAMPAS_R"
object-type="user" pool-name="PAMPAS_R">
<description />
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false"
associate-with-thread="false" connection-creation-retry-attempts="0"
connection-creation-retry-interval-in-seconds="10"
connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0"
connection-validation-method="table" datasource-classname="oracle.jdbc.pool.OracleDataSource"
fail-all-connections="false" idle-timeout-in-seconds="300"
is-connection-validation-required="false"
is-isolation-level-guaranteed="true" lazy-connection-association="false"
lazy-connection-enlistment="false" match-connections="false"
max-connection-usage-count="0" max-pool-size="32"
max-wait-time-in-millis="60000" name="PAMPAS_R"
non-transactional-connections="false" ping="false"
pool-resize-quantity="2" pooling="true" res-type="javax.sql.DataSource"
statement-cache-size="0" statement-leak-reclaim="false"
statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1"
steady-pool-size="8" validate-atmost-once-period-in-seconds="0"
validation-table-name="dual" wrap-jdbc-objects="true">
<description>PAMPAS_R</description>
<property name="URL" value="jdbc:oracle:thin:@server.dom:1669:db" />
<property name="User" value="username" />
<property name="Password" value="password" />
</jdbc-connection-pool>
</resources>
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<!-- <persistence-unit name="pampas-r" transaction-type="JTA"> -->
<persistence-unit name="pampas-r" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- <jta-data-source>java:app/jdbc/PAMPAS_R</jta-data-source> -->
<class>pampas.db.r.Indi</class>
<class>pampas.db.r.IndiHierarchy</class>
<class>pampas.db.r.IndiHierarchyPK</class>
<class>pampas.db.r.IndiRoot</class>
<class>pampas.db.r.Plugin</class>
<class>pampas.db.r.PluginGroup</class>
<class>pampas.db.r.PluginGroupKey</class>
<class>pampas.db.r.PluginGroupKeyPK</class>
<class>pampas.db.r.PluginKey</class>
<class>pampas.db.r.PluginKeyType</class>
<class>pampas.db.r.PluginKeyTypeDd</class>
<class>pampas.db.r.PluginKeyTypeDdPK</class>
<class>pampas.db.r.PluginValue</class>
<class>pampas.db.r.Script</class>
<class>pampas.db.r.Plant</class>
<class>pampas.db.r.Region</class>
<class>pampas.db.r.StatusText</class>
<class>pampas.db.r.Threshold</class>
<class>pampas.db.r.ThresholdPK</class>
<class>pampas.db.r.VSuppressActive</class>
<properties>
<property name="eclipselink.jdbc.batch-writing" value="JDBC" />
<property name="eclipselink.jdbc.cache-statements" value="false" />
<property name="eclipselink.jdbc.native-sql" value="true" />
<property name="javax.persistence.jdbc.url"
value="jdbc:oracle:thin:@server.dom:1541:db" />
<property name="javax.persistence.jdbc.user" value="username" />
<property name="javax.persistence.jdbc.password" value="password" />
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
</properties>
</persistence-unit>
</persistence>
An example of one of the JPA 2.0 entities is below:
package pampas.db.r;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* The persistent class for the INDI database table.
*
*/
@Entity
@NamedQueries({
@NamedQuery(name="Indi.findAll", query="SELECT i FROM Indi i"),
@NamedQuery(name="Indi.findByIndiKey", query="SELECT i FROM Indi i WHERE i.cidIndicatorKey = :indi_key"),
})
public class Indi implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="CID_INDICATOR_KEY")
private String cidIndicatorKey;
@Column(name="CFL_ACTIVE")
private String cflActive;
@Column(name="CFL_INDICATOR_TYPE")
private String cflIndicatorType;
@Column(name="CTX_DESC")
private String ctxDesc;
@Column(name="CTX_HYPERLINK")
private String ctxHyperlink;
@Column(name="CTX_TOOLTIP")
private String ctxTooltip;
@Column(name="NNO_TIMEOUT")
private BigDecimal nnoTimeout;
//bi-directional one-to-one association to IndiHierarchy
@OneToOne(mappedBy="childIndi")
private IndiHierarchy ancestor;
//bi-directional many-to-one association to IndiHierarchy
@OneToMany(mappedBy="parentIndi")
private List<IndiHierarchy> descendants;
//bi-directional one-to-one association to IndiRoot
@OneToOne(mappedBy="indi")
private IndiRoot indiRoot;
//bi-directional many-to-one association to PluginValue
@OneToMany(mappedBy="indi")
private List<PluginValue> pluginValues;
//bi-directional one-to-one association to Script
@OneToOne(mappedBy="indi")
private Script script;
//bi-directional many-to-one association to Threshold
@OneToMany(mappedBy="indi")
private List<Threshold> thresholds;
//bi-directional many-to-one association to VSuppressActive
@OneToMany(mappedBy="indi")
private List<VSuppressActive> vSuppressActives;
public Indi() {
}
public String getCidIndicatorKey() {
return this.cidIndicatorKey;
}
protected void setCidIndicatorKey(String cidIndicatorKey) {
this.cidIndicatorKey = cidIndicatorKey;
}
public String getCflActive() {
return this.cflActive;
}
protected void setCflActive(String cflActive) {
this.cflActive = cflActive;
}
public String getCflIndicatorType() {
return this.cflIndicatorType;
}
protected void setCflIndicatorType(String cflIndicatorType) {
this.cflIndicatorType = cflIndicatorType;
}
public String getCtxDesc() {
return this.ctxDesc;
}
protected void setCtxDesc(String ctxDesc) {
this.ctxDesc = ctxDesc;
}
public String getCtxHyperlink() {
return this.ctxHyperlink;
}
protected void setCtxHyperlink(String ctxHyperlink) {
this.ctxHyperlink = ctxHyperlink;
}
public String getCtxTooltip() {
return this.ctxTooltip;
}
protected void setCtxTooltip(String ctxTooltip) {
this.ctxTooltip = ctxTooltip;
}
public BigDecimal getNnoTimeout() {
return this.nnoTimeout;
}
protected void setNnoTimeout(BigDecimal nnoTimeout) {
this.nnoTimeout = nnoTimeout;
}
public IndiHierarchy getAncestor() {
return this.ancestor;
}
protected void setAncestor(IndiHierarchy ancestor) {
this.ancestor = ancestor;
}
public Indi getParent() {
try {
return this.getAncestor().getParentIndi();
} catch(NullPointerException e) {
return null;
}
}
public List<IndiHierarchy> getDescendants() {
return this.descendants;
}
protected void setDescendants(List<IndiHierarchy> descendants) {
this.descendants = descendants;
}
public List<Indi> getChildren() {
List<Indi> children = new ArrayList<Indi>();
for(IndiHierarchy descendant : getDescendants()) {
children.add(descendant.getChildIndi());
}
return children;
}
protected IndiHierarchy addDescendants(IndiHierarchy descendant) {
getDescendants().add(descendant);
descendant.setParentIndi(this);
return descendant;
}
protected IndiHierarchy removeDescendant(IndiHierarchy descendant) {
getDescendants().remove(descendant);
descendant.setParentIndi(null);
return descendant;
}
public IndiRoot getIndiRoot() {
return this.indiRoot;
}
protected void setIndiRoot(IndiRoot indiRoot) {
this.indiRoot = indiRoot;
}
public List<PluginValue> getPluginValues() {
return this.pluginValues;
}
protected void setPluginValues(List<PluginValue> pluginValues) {
this.pluginValues = pluginValues;
}
protected PluginValue addPluginValue(PluginValue pluginValue) {
getPluginValues().add(pluginValue);
pluginValue.setIndi(this);
return pluginValue;
}
protected PluginValue removePluginValue(PluginValue pluginValue) {
getPluginValues().remove(pluginValue);
pluginValue.setIndi(null);
return pluginValue;
}
public Script getScript() {
return this.script;
}
protected void setScript(Script script) {
this.script = script;
}
public List<Threshold> getThresholds() {
return this.thresholds;
}
protected void setThresholds(List<Threshold> thresholds) {
this.thresholds = thresholds;
}
protected Threshold addThreshold(Threshold threshold) {
getThresholds().add(threshold);
threshold.setIndi(this);
return threshold;
}
protected Threshold removeThreshold(Threshold threshold) {
getThresholds().remove(threshold);
threshold.setIndi(null);
return threshold;
}
public List<VSuppressActive> getVSuppressActives() {
return this.vSuppressActives;
}
protected void setVSuppressActives(List<VSuppressActive> vSuppressActives) {
this.vSuppressActives = vSuppressActives;
}
protected VSuppressActive addVSuppressActive(VSuppressActive vSuppressActive) {
getVSuppressActives().add(vSuppressActive);
vSuppressActive.setIndi(this);
return vSuppressActive;
}
protected VSuppressActive removeVSuppressActive(VSuppressActive vSuppressActive) {
getVSuppressActives().remove(vSuppressActive);
vSuppressActive.setIndi(null);
return vSuppressActive;
}
}
from __future__ import print_function
import java.lang.Class
import contextlib2 as contextlib
import javax.persistence.Persistence as JPA
indi_class = java.lang.Class.forName(u'pampas.db.r.Indi')
manager_factory = JPA.createEntityManagerFactory(u'pampas-r')
manager = manager_factory.createEntityManager()
with contextlib.closing(manager_factory.createEntityManager()) as manager:
indi = manager.createNamedQuery(u'Indi.findByIndiKey', indi_class)
indi = indi.setParameter(u'indi_key', u'SYSTEM_ROOT')
indi = indi.singleResult
print(indi.name)
One of the biggest things I did to alter my JPA entities is by setting the setters to protected, I essentially made the entities read-only. The user I am using to log into the database has only read-only access as well, but I just wanted to be doubly-certain I wasn’t doing anything with the data I shouldn’t be.
Anyway, as time permits, I will break down more of the pieces of making all of this “just work” for the project. I hope someone finds these helpful. If not, at least I have this documented *somewhere*.