我使用JPA / Spring / Hibernate作为我的应用程序的持久性机制。目前我遇到了单元测试问题,当我要求一些对象时,我从DAO返回的数量与数据库中的行数相对应,但它们都是完全相同的实例。这是导致问题的findByName()方法。
public class ActionDefinitionDaoJpa extends JpaDaoSupport implements IActionDefinitionDao { public List findByName( String name ) { return getJpaTemplate().find("from ActionDefinition where listenerName = ?", name ); } }
此方法可以正常运行。我在DAO层而不是服务层测试这个,所以我没有在测试中的任何位置引入任何事务。我不知道它是否是交易性的。如果我使用JPA生成的SQL并执行它,我会从数据库中获得正确的结果集。
这是我的spring配置文件和persistence.xml文件
<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>
这是我的persistence.xml文件
<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>
这是我的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;
}
...
...
}
我玩过许多不同的组合,例如从 LocalContainerEntityManagerFactoryBean 更改为 LocalEntityManagerFactoryBean 。
我收到有关persistenceXmlLocation属性不存在的运行时错误。
我还尝试将persistance.xml文件中的事务类型更改为“JTA”,这似乎没有用,它实际上已经破坏了它。
此时我正在挣扎,不知道我的问题在哪里。我再次在JUnit中运行它,因此它不在任何容器内,并且可能在移动到Production时。
任何指针都会受到赞赏;感谢
答案 0 :(得分:1)
感谢您提供的意见:我已经确定了我的问题所在。我得到ActionDefinition实例完全相同的原因是因为我的表包含一个复合主键。
以下是我使用模型对象解决问题的方法。我将模型对象更改为包含名为ActionDefinitionPK
的Composite类
@Entity
@Table(name="PUT_M_DEFINITION")
@IdClass(ActionDefinitionPK.class)
public class ActionDefinition implements java.io.Serializable {
@Id
@Column (name="LISTENER_NAME")
private String listenerName = null;
@Id
@Column (name="CONTEXT")
private String context = null;
@Column (name="DATA")
private String data = null;
@Column (name="NOTES")
private String notes = null;
@Column (name="EMAIL_ID")
private String emailId = null;
这是Composite类及其定义
@Embeddable
public class ActionDefinitionPK implements java.io.Serializable {
@Column (name="LISTENER_NAME")
private String listenerName = null;
@Column (name="CONTEXT")
private String context = null;
/**
* Constructor
*/
public ActionDefinitionPK() {
}
public ActionDefinitionPK(String name, String context) {
setListenerName( name );
setContext( context );
}
}
Thanks to all those who provided help.