JPA Spring Hibernate Dao列表问题

时间:2009-12-17 21:40:01

标签: hibernate spring jpa

我使用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时。

任何指针都会受到赞赏;感谢

1 个答案:

答案 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.