Skip to content

CHill's Ramblings

Thoughts, ideas, and other such things I feel like putting here. About basically any topic.

Making Jython 2.7 talk to JPA 2.0 in Glassfish 3.1 with JNDI

Posted on September 15, 2016August 2, 2021 By darkhelm No Comments on Making Jython 2.7 talk to JPA 2.0 in Glassfish 3.1 with JNDI
0 0
Read Time:8 Minute, 18 Second

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.

One of the first things I had to do was to get JPA 2.0 entities to be accessible in Jython 2.7. I also had to define my connections as connection pools in glassfish-resources.xml.
My glassfish-resources.xml looks something like this:

<?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>
I then had to construct a persistence.xml for JPA to work
<?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>

I listed multiple classes, which I had to define the JPA entities for them. I did not have them automatically generated, because I want some specialized controls. I also needed to make sure I had the correct oracle driver for Java in my WAR.

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;
}

}
I needed to ensure that my path where the class files are built are in my PYTHONPATH environment variable so I can access them directly from the Jython code. Finally, I need Jython to access JPA and get entities from the DB.

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)
This very simply let me access the Oracle database using JPA 2.0 through Jython 2.7 on Glassfish 3.1 with JNDI. All of this insanity was the beginning of my frustrations with my project. Especially as there was simply no documentation anywhere to help with this at all, so I had to stretch my knowledge of how systems work to achieve success.

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*.

Share

Facebook
Twitter
Pinterest
LinkedIn

About Post Author

darkhelm

chill@darkhelm.org
http://darkhelm.org
Happy
Happy
0 0 %
Sad
Sad
0 0 %
Excited
Excited
0 0 %
Sleepy
Sleepy
0 0 %
Angry
Angry
0 0 %
Surprise
Surprise
0 0 %
glassfish, jpa, jython

Post navigation

Previous Post: Jython, JPA, Glassfish, Blueprints (BitsyGraph)… How to drive yourself crazy in 10 easy steps.
Next Post: So tired of the political stuff, when’s the election over?

Average Rating

5 Star
0%
4 Star
0%
3 Star
0%
2 Star
0%
1 Star
0%
(Add your review)

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Archives

  • October 2021
  • August 2021
  • October 2019
  • November 2018
  • October 2016
  • September 2016
  • November 2015
  • September 2013
  • May 2013
  • October 2012
  • April 2012
  • March 2012
  • December 2010
  • November 2010
  • September 2010
  • August 2010
  • July 2010
  • January 2010

Categories

  • america
  • bitsy
  • blueprints
  • ejb
  • glassfish
  • gwt-syntaxhighlighter
  • jpa
  • jython
  • lies
  • network
  • politics
  • Uncategorized

Recent Posts

  • To Dave Hines, my friend, may you now have the joy you had spread to everyone around you.
  • Router Fun
  • False Peace
  • Moving away from the google universe.
  • The problem with people abusing scripture to attack entertainment

Recent Comments

  1. darkhelm on To Dave Hines, my friend, may you now have the joy you had spread to everyone around you.
  2. Matt Sutton on To Dave Hines, my friend, may you now have the joy you had spread to everyone around you.
  3. Unknown on Jonah, Jonah, did not obey God immediately…
  4. 1seanv on A Christian’s Response To: A Christian’s View of World of Warcraft (published in 2008)
  5. Unknown on Jonah, Jonah, did not obey God immediately…

Copyright © 2023 CHill's Ramblings.

Powered by PressBook WordPress theme