Java EE 7 is around for a few years already, and provides several very useful and long-awaited features, like entity graphs and better support for stored procedures and results mapping. For an overview, have a look at Thorben Janssen’s blog post. The query capabilities were also enhanced, with 3 additional keywords. All of them are available in both JPQL and Criteria API:

  • ON keyword to specify conditions for JOINs
  • FUNCTION to call arbitrary database function
  • TREAT to downcast entities to their specific type

In this post, I’ll focus on the first of them – the ON keyword in JOINs.

(more…)

JPA provides essentially 2 types of locking mechanisms to help synchronize access to entities. Both mechanisms prevent a scenario, where 2 transactions overwrite data of each other without knowing it.

By entity locking, we typically want to prevent following scenario with 2 parallel transactions:

  1. Adam’s transaction reads data X
  2. Barbara’s transaction reads data X
  3. Adam’s transaction modifies data X, and changes it to XA
  4. Adam’s transaction writes data XA
  5. Barbara’s transaction modifies data X and changes it to XB
  6. Barbara’s transaction writes data XB

As a result, changes done by Adam are completely gone and overwritten by Barbara without her even noticing. A scenario like this is sometimes called dirty-read. Obviously, a desired result is that Adam writes XA, and Barbara is forced to review XA changes before writing XB.

How Optimistic Locking works

(more…)

When tried to tune our near-production application, we came to problem when a single entity reference When tried to tune our near-production application, we came to problem when a single entity reference (not a collection) is loaded lazily. We used inheritance with this entity and hibernate JPA provider (as probably any other provider) inserts a proxy object into referencing entity instead of reference to real object loaded from database (as it is not yet loaded).

We came to a problem because we were casting super class to subclasses using instanceof. The problem is that proxy class is already a subclass and cannot be cast to a sibling class. It is a proxy only to super class instance, but it’s not possible to access methods of superclasses directly. The proxy never gets converted to real subclass. The problem is specified here, here and here. All described solutions depend on hibernate non-standard API to retrieve deproxied instance.

However, after lots of thinking…

… I found a solution to deproxy a class using standard Java and JPA API. Tested with hibernate, but does not require hibernate as a dependency and should work with all JPA providers.

Only one requirement – its necessary to modify parent class (Address) and add a simple helper method.

General idea: add helper method to parent class which returns itself. when method called on proxy, it will forward the call to real instance and return this real instance.

Implementation is a little bit more complex, as hibernate recognizes that proxied class returns itself and still returns proxy instead of real instance. Workaround is to wrap returned instance into a simple wrapper class, which has different class type than the real instance.

In code:

class Address {
  public AddressWrapper getWrappedSelf() {
    return new AddressWrapper(this);
  }
...
}

class AddressWrapper {
  private Address wrappedAddress;
...
}

 

To cast Address proxy to real subclass, use following:

Address address = dao.getSomeAddress(...);
Address deproxiedAddress = address.getWrappedSelf().getWrappedAddress();
if (deproxiedAddress instanceof WorkAddress) {
  WorkAddress workAddress = (WorkAddress)deproxiedAddress;
}

 

List of elements in persistence.xml

<!-- turn off 2nd level caching (optional), values:
 NONE, ALL, DISABLE_SELECTIVE, ENABLE_SELECTIVE,  -->

<shared-cache-mode>NONE</shared-cache-mode>

<!-- desired provider (optional), 
 if not present, default provider will be used -->

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

<!-- if true, only listed classes will be treated as entities. 
  Default false. 
  Not applicable for Java SE, where every entity must be listed -->

<exclude-unlisted-classes>false</exclude-unlisted-classes>

<!-- optional declaration of used datasource. 
  If not specified, connection properties must be specified.
  Otherwise will use the referenced datasource provided by the container -->

<jta-data-source>jdbc/ds</jta-data-source>
Code language: HTML, XML (xml)

These elements can be overridden with the following properties, if a map is passed to EntityManagerFactory:

  • javax.persistence.provider to define the provider class used
  • javax.persistence.transactionType to define the transaction type used (either JTA or RESOURCE_LOCAL)
  • javax.persistence.jtaDataSource to define the JTA datasource name in JNDI
  • javax.persistence.nonJtaDataSource to define the non JTA datasource name in JNDI
  • javax.persistence.lock.timeout – pessimistic lock timeout in milliseconds (Integer or String)
  • javax.persistence.query.timeout – query timeout in milliseconds (Integer or String)
  • javax.persistence.sharedCache.mode corresponds to the share-cache-mode element defined in Section 2.2.1, “Packaging”
  • javax.persistence.validation.mode corresponds to the validation-mode element defined in Section 2.2.1, “Packaging”

See Hibernate 3.5 reference

List of standard properties

Driver:

<property name="javax.persistence.jdbc.driver" 
  value="org.apache.derby.jdbc.ClientDriver"/>Code language: HTML, XML (xml)

URL:

<property name="javax.persistence.jdbc.url" 
  value="jdbc:derby://localhost:1527/chapter02DB;create=true"/>Code language: HTML, XML (xml)

User:

<property name="javax.persistence.jdbc.user" value="APP"/>Code language: HTML, XML (xml)

Password:

<property name="javax.persistence.jdbc.password" value="APP"/>Code language: HTML, XML (xml)

Hibernate properties

Debug SQL:

<property name="hibernate.show_sql" value="true"/>Code language: HTML, XML (xml)

Schema generation (optional):

<!-- create the database schema automatically,
  values: create-drop, update -->

<property name="hibernate.hbm2ddl.auto" 
  value="create-drop"/>

Code language: HTML, XML (xml)

Dialect:

<property name="hibernate.dialect" 
  value="org.hibernate.dialect.H2Dialect" />Code language: HTML, XML (xml)

EclipseLink properties

Schema generation (optional):

<!-- create the database schema automatically, 
  values: create-tables, drop-and-create-tables -->

<property name="eclipselink.ddl-generation" 
  value="create-tables"/>Code language: HTML, XML (xml)

Resources

This site uses cookies to improve your experience. By using this site you agree to these cookies being set. More in our cookies policy

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close