Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne (FetchType.Lazy ignored by Eclipselink)
Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #560235] Tue, 21 September 2010 15:58 Go to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
Hi,

we currently develop a J2EE enterprise application and using Glassfish 3.0.1 with the bundled EclipseLink. I think its 2.0.1. In our application we have several OneToOne relationships between Entitys and we defined them all with @OneToOne(fetch = FetchType.LAZY). But when analyzing the logs we saw that these relations were fetched eagerly by EclipseLink.

So we created two test entitys as follows:

TestA.class
@Entity
@Table(name = "testa")
public class TestA implements Serializable {

	@Id
	@SequenceGenerator(name="TESTA_ID_GENERATOR", sequenceName="TESTA_ID_SEQ")
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TESTA_ID_GENERATOR")
	private Long id;

        public TestA() {
        }

	public Long getId() {
		return this.id;
	}

}


TestB.class
@Entity
@Table(name = "testb")
public class TestB implements Serializable {

	@Id
	@SequenceGenerator(name="TESTB_ID_GENERATOR", sequenceName="TESTB_ID_SEQ")
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TESTB_ID_GENERATOR")
	private Long id;

	//uni-directional one-to-one association to TestA
	@OneToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "testa_id")
	private TestA testa;

        public TestB() {
        }

	public Long getId() {
		return this.id;
	}

	public TestA getTesta() {
		return this.testa;
	}

	public void setTesta(TestA testa) {
		this.testa = testa;
	}
	
}


Now when we call EntityManager.findById(TestB.class, id) the logs show that EclipseLink first fetches TestB from the database and then the associated TestA. When we then call TestB.getTesta() no database query will be performed because EclipseLink already knows the associated TestA.

The EntityManager we used in our application is not container managed. Our application needs to switch customer databases dynamically based on the web URL (www.example.com/customer1 results in an EntityManagerFactory with a datasource for the database of customer1). Here is the code:
    public EntityManager aquireEntityManager(String uniqueCustomerName) {
    	
    	EntityManagerFactory emf = this.emfMap.get(uniqueCustomerName);
    	
    	if(emf == null) {
    		
            Map<String,String> emProperties = new HashMap<String, String>();
            emProperties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "jdbc/PostgreSQL_backend-" + uniqueCustomerName);
            
            emf = Persistence.createEntityManagerFactory("backend-jpaPU", emProperties);
            emf.getCache().evictAll();

            this.emfMap.put(uniqueCustomerName, emf);
            
    	}
    	
    	EntityManager em = emf.createEntityManager();
    	
    	return em;
    	
    }



As we create our EntityManager "by hand" do we need to tell EclipseLink to use dynamic weaving on our entities so that OneToOne lazy loading will work? If so, how should we do it? We tried adding <property name="eclipselink.weaving" value="true"/> to our persistence.xml but this causes an exception: org.eclipse.persistence.exceptions.EntityManagerSetupExcepti on Exception Description: Value [true] for the property [eclipselink.weaving] is incorrect when global instrumentation is null, value should either be null or false.

So how can we activate lazy loading in our scenario? We thought that dynamic weaving is the default behavior when EclipseLink is used in an J2EE context like Glassfish.



Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #560751 is a reply to message #560235] Tue, 21 September 2010 16:10 Go to previous messageGo to next message
Fericit Bostan is currently offline Fericit BostanFriend
Messages: 68
Registered: June 2010
Member
Why not use static weaving instead? It is easily configured through ant and maven.


Maven:
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>JPA Enhancement</id>
                        <phase>process-classes</phase>
                        <configuration>
                            <tasks>
                                <java
                                    classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
                                    classpathref="maven.test.classpath"
                                    fork="true">
                                    <arg
                                        line="-loglevel FINEST -persistenceinfo src/main/resources target/classes target/classes" />
                                </java>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>



Ant:
<?xml version="1.0"?>
<project name="jpa-weaving" default="weaving" basedir="./../..">
    <property environment="env"/>
    <property name="glassfish.home" value="${env.GLASSFISH_HOME}"/>
    <path id="weavingclasspath">
        <pathelement location="${glassfish.home}/lib/javaee.jar"/>
        <pathelement location="${basedir}/lib/eclipselink.jar"/>
    </path>
	
    <target name="define.task" description="New task definition for EclipseLink static weaving"	>
        <taskdef name="weave" classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeaveAntTask">
            <classpath refid="weavingclasspath"/>
        </taskdef>
    </target>

    <target name="weaving" description="perform weaving" depends="define.task">
        <weave source="${basedir}/target/classes" target="${basedir}/target/classes">
            <classpath refid="weavingclasspath"/>
        </weave>
    </target>
</project>
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #560752 is a reply to message #560235] Tue, 21 September 2010 16:11 Go to previous messageGo to next message
Fericit Bostan is currently offline Fericit BostanFriend
Messages: 68
Registered: June 2010
Member
Why not use static weaving instead? It is easily configured through ant and maven.


Maven:
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>JPA Enhancement</id>
                        <phase>process-classes</phase>
                        <configuration>
                            <tasks>
                                <java
                                    classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
                                    classpathref="maven.test.classpath"
                                    fork="true">
                                    <arg
                                        line="-loglevel FINEST -persistenceinfo src/main/resources target/classes target/classes" />
                                </java>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>



Ant:
<?xml version="1.0"?>
<project name="jpa-weaving" default="weaving" basedir="./../..">
    <property environment="env"/>
    <property name="glassfish.home" value="${env.GLASSFISH_HOME}"/>
    <path id="weavingclasspath">
        <pathelement location="${glassfish.home}/lib/javaee.jar"/>
        <pathelement location="${basedir}/lib/eclipselink.jar"/>
    </path>
	
    <target name="define.task" description="New task definition for EclipseLink static weaving"	>
        <taskdef name="weave" classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeaveAntTask">
            <classpath refid="weavingclasspath"/>
        </taskdef>
    </target>

    <target name="weaving" description="perform weaving" depends="define.task">
        <weave source="${basedir}/target/classes" target="${basedir}/target/classes">
            <classpath refid="weavingclasspath"/>
        </weave>
    </target>
</project>
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #560753 is a reply to message #560235] Tue, 21 September 2010 16:11 Go to previous messageGo to next message
Fericit Bostan is currently offline Fericit BostanFriend
Messages: 68
Registered: June 2010
Member
Why not use static weaving instead? It is easily configured through ant and maven.


Maven:
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>JPA Enhancement</id>
                        <phase>process-classes</phase>
                        <configuration>
                            <tasks>
                                <java
                                    classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeave"
                                    classpathref="maven.test.classpath"
                                    fork="true">
                                    <arg
                                        line="-loglevel FINEST -persistenceinfo src/main/resources target/classes target/classes" />
                                </java>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>



Ant:
<?xml version="1.0"?>
<project name="jpa-weaving" default="weaving" basedir="./../..">
    <property environment="env"/>
    <property name="glassfish.home" value="${env.GLASSFISH_HOME}"/>
    <path id="weavingclasspath">
        <pathelement location="${glassfish.home}/lib/javaee.jar"/>
        <pathelement location="${basedir}/lib/eclipselink.jar"/>
    </path>
	
    <target name="define.task" description="New task definition for EclipseLink static weaving"	>
        <taskdef name="weave" classname="org.eclipse.persistence.tools.weaving.jpa.StaticWeaveAntTask">
            <classpath refid="weavingclasspath"/>
        </taskdef>
    </target>

    <target name="weaving" description="perform weaving" depends="define.task">
        <weave source="${basedir}/target/classes" target="${basedir}/target/classes">
            <classpath refid="weavingclasspath"/>
        </weave>
    </target>
</project>
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #588031 is a reply to message #560753] Tue, 21 September 2010 17:56 Go to previous messageGo to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
Thanks for your reply.

Static weaving would be the next thing we will try. But if it works it feels like a workaround.

As stated in http:// wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Wha t_You_May_Need_to_Know_About_EclipseLink_JPA_Lazy_Loading we thought OneToOne Lazy Loading should work out of the box with Glassfish 3.x.x and EclipseLink.

Quote:

If you are developing your application in a Java EE environment, you only have to set fetch to javax.persistence.FetchType.LAZY, and EclipseLink persistence provider will supply all the necessary functionality.

When using a one-to-one or many-to-one mapping in a Java SE environment, to configure EclipseLink JPA to perform lazy loading when the fetch attribute is set to FetchType.LAZY, configure either dynamic or static weaving.

When using a one-to-one or many-to-one mapping in a Java SE environment that does not permit the use of -javaagent on the JVM command line, to configure EclipseLink JPA to perform lazy loading when annotation attribute fetch is set to javax.persistence.FetchType.LAZY, you can use static weaving.



Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #594168 is a reply to message #588031] Tue, 21 September 2010 18:29 Go to previous messageGo to next message
Fericit Bostan is currently offline Fericit BostanFriend
Messages: 68
Registered: June 2010
Member
The default fetch type behavior in GlassFish 3.x, with EclipseLink, is to lazily load your associations. However, as you have stated, your not exactly using the EntityManager in the default fashion. For that reason, I would imagine that it is best to be explicit and define all of the behavior you expect in your persistence.xml file.

While dynamic weaving is absolutely wonderful (simply because it works without having to do anything) the recommended approach for weaving is statically. Usually, dynamic weaving is for development purposes only. Seeing as you can have ant or maven perform the static weaving for you every time the project is built, or Eclipse can perform it for you also if using ant, maven or even Dali, there is really no reason to not perform the static weave. You're going to need it once you go into production anyway so why not simply bring it into the build process from the beginning.

http:// wiki.eclipse.org/Introduction_to_EclipseLink_Application_Dev elopment_%28ELUG%29#Using_Weaving
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #626235 is a reply to message #560235] Wed, 22 September 2010 13:00 Go to previous messageGo to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
We have changed our ant file to use static weaving and now OneToOne lazy loading seems to work fine in our application.

Thanks for your help.
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #628650 is a reply to message #560235] Thu, 23 September 2010 14:30 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

It seems like EclipseLink is not getting the weaving callbacks from Glassfish when the persistence unit is not container managed. Does it work if you make the persistence unit container manager?

You may be able to configure a second persistence unit with the same classes that is container managed, then the classes should get weaved.

You can enable logging on finest to see if weaving is occurring.


James : Wiki : Book : Blog : Twitter
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #628857 is a reply to message #628650] Fri, 24 September 2010 13:23 Go to previous messageGo to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
When we create a new persistence unit (without setting eclipselink.weaving to true) and inject this persistence unit via @PersistenceContext then glassfish does weaving some classes during application deployment and when the injected EntityManager is accessed the first time all other classes will be weaved by glassfish.

So weaving with container managed persistence unit works but it does not work when creating EntityManagers by hand as we are forced to do. Maybe a bug?

BTW: Although static weaving works fine now we have an issue with persisting a map in our application. With static weaving and with enabled changetracking, map entries won't get persisted. See http://www.eclipse.org/forums/index.php?t=msg&th=197197& amp;start=0 for details.
Re: Glassfish 3.0.1 + bundled EclipseLink (2.0.1) Lazy loading OneToOne [message #688754 is a reply to message #560753] Sat, 25 June 2011 15:48 Go to previous message
Craig Day is currently offline Craig DayFriend
Messages: 4
Registered: June 2011
Junior Member
I have created a native maven plugin to execute the weaver:
    <build>
        <plugins>
            <plugin>
                <artifactId>eclipselink-staticweave-maven-plugin</artifactId>
                <groupId>au.com.alderaan</groupId>
                <version>1.0.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>weave</goal>
                        </goals>
                        <phase>process-classes</phase>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Further information available at code.google.com/p/eclipselink-staticweave-maven-plugin/
Previous Topic:(no subject)
Next Topic:Executing arbitrary SQL in the current session
Goto Forum:
  


Current Time: Mon Dec 22 23:41:03 GMT 2014

Powered by FUDForum. Page generated in 0.11479 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software