【问题标题】:JPA Spring Hibernate Dao List problemJPA Spring Hibernate Dao List 问题
【发布时间】:2010-12-27 20:12:51
【问题描述】:

我使用 JPA/Spring/Hibernate 作为我的应用程序的持久性机制。目前我遇到了单元测试问题,当我请求一些对象时,我从 DAO 返回了与数据库中的行数相对应的正确数量,但它们都是完全相同的实例。这是导致我出现问题的 findByName() 方法。

公共类 ActionDefinitionDaoJpa 扩展 JpaDaoSupport 实现 IActionDefinitionDao { 公共列表 findByName( 字符串名称 ) { 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 文件中的transaction-type 更改为“JTA”,但这似乎不起作用,实际上却破坏了它。

此时我正在挣扎,不知道我的问题出在哪里。我再次在 JUnit 中运行它,因此它不在任何容器内,并且可能在移至生产环境时出现。

任何指针将不胜感激;谢谢

【问题讨论】:

  • 给出异常的整个堆栈跟踪 - 这是最重要的..
  • 我没有收到 StackTrace 错误;返回的对象是完全相同的实例;请参阅下面的输出 #### List = [com.putnam.compliance.cme.model.actions.ActionDefinition@12b3349[ listenerName=DEF_TESTING context=ListenerOne data=First JUnit notes=这是用于纯 JUnit 测试。 emailId=peter.delaney@putnam.com ], com.putnam.compliance.cme.model.actions.ActionDefinition@12b3349[ listenerName=DEF_TESTING context=ListenerOne data=First JUnit notes=这用于纯 JUnit 测试。 emailId=peter.delaney@putnam.com ]]

标签: hibernate spring jpa


【解决方案1】:

感谢您提供的意见:我已经确定我的问题是什么。我得到完全相同的 ActionDefinition 实例的原因是因为我的表包含一个复合主键。

这是我解决模型对象问题的方法。我将模型对象更改为包含一个名为 ActionDefinitionPK 的复合类


@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.

【讨论】:

    猜你喜欢
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    相关资源
    最近更新 更多