2009-12-17 3 views
1

Я использую JPA/Spring/Hibernate как мой механизм сохранения для моего приложения. В настоящее время я сталкиваюсь с проблемами с единичным тестированием, когда, когда я запрашиваю некоторые объекты, я получаю правильную сумму, возвращенную из DAO, которая соответствует количеству строк в базе данных, но все они являются одним и тем же экземпляром. Вот метод findByName(), который вызывает у меня проблему.JPA Spring Hibernate Dao Задача списка

 
public class ActionDefinitionDaoJpa extends JpaDaoSupport implements IActionDefinitionDao { 
    public List findByName(String name) { 
     return getJpaTemplate().find("from ActionDefinition where listenerName = ?", name); 
    } 
} 

Этот метод работает без ошибок. Я тестирую это на уровне DAO, а не на уровне сервиса, поэтому у меня нет транзакций, введенных где-либо в тесте. Я не знаю, является ли оно транзакционным или нет. Если я беру SQL, который создает и выполняет JPA, я получаю правильный набор результатов из базы данных.

Вот мой конфигурационный файл весной и 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 боб


@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 Вы играли со многими различными комбинациями, такими как изменение от LocalContain erEntityManagerFactoryBean - LocalEntityManagerFactoryBean.

У меня возникли ошибки времени выполнения persistenceXmlLocation свойства нет.

Я также попытался сменить тип транзакции в файле persistance.xml на «JTA», который, похоже, не работал, он фактически сломал его.

На данный момент я барахтаюсь и не уверен, где моя проблема. Снова я запускаю это в JUnit, поэтому он не находится внутри какого-либо контейнера и может быть при перемещении в Production.

Любые указатели будут оценены по достоинству; спасибо

+0

дать всю StackTrace от exceptio - это самое главное .. – Bozho

+0

Я не получаю ошибку StackTrace; Возвращаемые объекты - это те же самые экземпляры; См выход ниже #### List = [[email protected] [ listenerName = DEF_TESTING контекст = ListenerOne данных = Первый JUnit ноты = Это для чистого тестирования JUnit. [email protected] ], com.putnam.compliance.cme.model.actions.ActionDefinition @ 12b3349 [ listenerName = DEF_TESTING context = ListenerOne data = First JUnit notes = Это для чистого тестирования JUnit. [email protected] ]] –

ответ

1

Спасибо за введенный ввод: Я определяю, в чем моя проблема. Причина, по которой я возвращался к экземпляру ActionDefinition, был то же самое, потому что моя таблица содержала Composite Primary Key.

Вот как я решил проблему с моим объектом модели. Я изменил мою модель объекта содержит композитный класс под названием 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; 


Вот композитный класс и его определение


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