JPA Spring Hibernate Дао Список проблем - PullRequest
1 голос
/ 18 декабря 2009

Я использую 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, а не на уровне сервиса, поэтому у меня нет транзакций, введенных где-либо в тесте. Я не знаю, является ли это транзакционным или нет. Если я возьму 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;
    }

   ...
   ...
}

Я играл со многими различными комбинациями, такими как изменение с LocalContainerEntityManagerFactoryBean на LocalEntityManagerFactoryBean .

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

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

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

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

1 Ответ

1 голос
/ 21 декабря 2009

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

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