I am using JPA/Spring/Hibernate as my persistence mechanism for my application. Currently I am running into unit test problems where when I ask for some objects I get the right amount returned from the DAO that correspond to the number of rows in the database, but they are all of the exact same instance. Here is the findByName() method that is causing me the problem.
public class ActionDefinitionDaoJpa extends JpaDaoSupport implements IActionDefinitionDao { public List findByName( String name ) { return getJpaTemplate().find("from ActionDefinition where listenerName = ?", name ); } }
This method works without any errors. I am testing this at the DAO layer and not the Service layer so I have no transactions introduced any where in the test. I don't know if it is transactional or not. If I take the SQL that the JPA produces and execute it I get the right resultset from the database.
Here is my spring configuration file and persistence.xml file
<beans>
<!-- My Dao in Test -->
<bean id="actionDefinitionDao" class="com.putnam.compliance.cme.dao.actions.jpa.ActionDefinitionDaoJpa">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="persistenceUnitName" value="cmeJpa" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="ORACLE"/>
<property name="showSql" value="true"/>
<property name="generateDdl" value="false"/>
<property name="databasePlatform" value="org.hibernate.dialect.OracleDialect"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.transaction.flush_before_completion" value="true"/>
<entry key="hibernate.transaction.auto_close_session" value="true"/>
<entry key="hibernate.current_session_context_class" value="jta"/>
<entry key="hibernate.connection.release_mode" value="auto"/>
</map>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<!--
DataSource to talk to Database Note: these values are pulled in by the .properties files
-->
<bean id="localDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
<property name="driverClassName" value="${dataSource.driverClassName}" />
<property name="url" value="${dataSource.url}" />
<property name="username" value="${dataSource.username}" />
<property name="password" value="${dataSource.password}" />
</bean>
<alias name="localDataSource" alias="dataSource"></alias>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource"/>
</bean>
</bean>
Here is my persistence.xml file
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<!--
<persistence-unit name="cmeJpa" transaction-type="JTA">
-->
<persistence-unit name="cmeJpa" transaction-type="RESOURCE_LOCAL">
<class>com.putnam.compliance.cme.model.actions.ActionSequence</class>
<class>com.putnam.compliance.cme.model.actions.ActionDefinition</class>
<class>com.putnam.compliance.cme.model.actions.ActionXmlDefinition</class>
<exclude-unlisted-classes/>
</persistence-unit>
</persistence>
Here is my ActionDefinition JPA bean
@Entity
@Table(name="PUT_M_DEFINITION")
public class ActionDefinition implements java.io.Serializable {
public ActionDefinition() {
}
@Id
@Column(name="LISTENER_NAME")
public String getListenerName() {
return listenerName;
}
public void setListenerName( String n ) {
listenerName = n;
}
@Column(name="CONTEXT")
public String getContext() {
return context;
}
public void setContext( String n ) {
context = n;
}
@Column(name="DATA")
public String getData() {
return data;
}
public void setData( String n ) {
data = n;
}
@Column(name="NOTES")
public String getNotes() {
return notes;
}
public void setNotes( String n ) {
notes = n;
}
@Column(name="EMAIL_ID")
public String getEmailId() {
return emailId;
}
public void setEmailId( String n ) {
emailId = n;
}
...
...
}
I've played with many different combinations like change from LocalContainerEntityManagerFactoryBean to a LocalEntityManagerFactoryBean.
I got runtime errors about persistenceXmlLocation property not present.
I also tried changing the transaction-type in persistance.xml file to "JTA" that did not seem to work it actually broke it.
At this point I am floundering and not sure where my problem is. Again I run this in JUnit so it is not inside any container and may be when moved to Production.
Any pointers would be appreciated; thanks