Hello,
I encountered a strange problem. I was setting up a simple JPA example using LocalEntityManagerFactoryBean and toplink in order to measure some performance figures over toplink cache. But when I switched to LocalContainerEntityManagerFactoryBean the toplink cache stopped working.
BTW I am using spring-2.5.3 and toplink 2.0-b41-beta2
So here the are my configurations:
A simple entity:
A simple service:Code:package entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="orders") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public int id; public String name; public Order() {} public Order(String name) { this.name = name; } @Override public String toString() { return id+"/"+name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final Order other = (Order) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
The two teste cases:Code:package services; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import entities.Order; @Service public class DBService { @PersistenceContext private EntityManager em; @Transactional public Order findOrder(int id) { return em.find(Order.class, id); } @Transactional public int insertOrder(String name) { Order no = new Order(name); em.persist(no); em.flush(); return no.id; } }
andCode:package tests; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import entities.Order; import services.DBService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:beans-local.xml"}) public class TestLocal { @Autowired private DBService dbs; // @Test // public void testCacheInsert() { // int id = dbs.insertOrder("hola"); // Order o1 = dbs.findOrder(id); // Order o2 = dbs.findOrder(id); // Assert.assertNotNull(o1); // Assert.assertEquals(o1, o2); // } @Test public void testCacheNoInsert() { int id = 14; Order o1 = dbs.findOrder(id); Order o2 = dbs.findOrder(id); Assert.assertNotNull(o1); Assert.assertEquals(o1, o2); } }
and the two configurations ( first the local one )Code:package tests; import org.springframework.test.context.ContextConfiguration; @ContextConfiguration(locations={"classpath:beans-container.xml"}) public class TestContainer extends TestLocal {}
beans-local.xml:
and the needed persistence.xml ( located in META-INF dir )<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schem...ng-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean class="org.springframework.orm.jpa.support.Persist enceAnnotationBeanPostProcessor"/>
<context:annotation-config />
<context:component-scan base-package="services" />
<tx:annotation-driven transaction-manager="jpaTM"/>
<bean id="jpaTM" class="org.springframework.orm.jpa.JpaTransactionM anager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityMana gerFactoryBean">
<property name="persistenceUnitName" value="arena" />
</bean>
</beans>
and the configuration files used for local-container:<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="arena" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistencePro vider</provider>
<class>entities.Order</class>
<properties>
<property name="toplink.logging.level" value="FINE" />
<property name="toplink.jdbc.user" value="******" />
<property name="toplink.jdbc.password" value="******" />
<property name="toplink.jdbc.url" value="jdbc:db2://localhost:50004/arena" />
<property name="toplink.jdbc.driver" value="com.ibm.db2.jcc.DB2Driver" />
</properties>
</persistence-unit>
</persistence>
beans-container.xml
and the corresponding persistence-container.xml<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schem...ng-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean class="org.springframework.orm.jpa.support.Persist enceAnnotationBeanPostProcessor"/>
<context:annotation-config />
<context:component-scan base-package="service" />
<context:load-time-weaver weaver-class="org.springframework.instrument.classloading .InstrumentationLoadTimeWeaver"/>
<tx:annotation-driven transaction-manager="jpaTM"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="url" value="jdbc:db2://localhost:50004/arena" />
<property name="username" value="********" />
<property name="password" value="********" />
<property name="driverClassName" value="com.ibm.db2.jcc.DB2Driver" />
</bean>
<bean id="jpaTM"
class="org.springframework.orm.jpa.JpaTransactionM anager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerE ntityManagerFactoryBean">
<property name="persistenceUnitName" value="arena" />
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="META-INF/persistence-container.xml"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJ paVendorAdapter">
<property name="showSql" value="true"/>
<property name="databasePlatform" value="oracle.toplink.essentials.platform.database .DB2Platform"/>
</bean>
</property>
</bean>
</beans>
The container test case was started with -javaagent:lib/spring-agent.jar option of course.<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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_1_0.xsd">
<persistence-unit name="arena" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistencePro vider</provider>
<properties>
<property name="toplink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
I knew that the cache was not working after monitorig the logs and observing that in the case of local-container test case the runtime issues two selects to the DB:
Since this is a simple setup I can provide the whole eclipse jar-ed project.[TopLink Fine]: 2008.04.14 10:44:14.301--ClientSession(25537913)--Connection(20978984)--Thread(Thread[main,5,main])--SELECT ID, NAME FROM orders WHERE (ID = ?)
bind => [14]
The commented method testCacheInsert was used to insert some orders into the database. Event stranger is that if only this method is used the runtime does not (in either cases) issues any select statements to the DB. So if one wants to reproduce the problem, run one of the test with testCacheInsert uncommented (or just insert a row into the db ) and after that run the two test cases as they are posted here. ( em.flush(); from the insertOrder method is neccesary for running testCacheInsert method )
Any help would be appreciated.
Regards,
Horia


Reply With Quote