Google genericdao框架使用Maven,Spring和Hibernate执行不必要的选择

时间:2014-09-30 18:28:16

标签: java hibernate genericdao

我使用的是Hibernate 4.2.11 Final,Spring 3.2.4和Google Genericdao 1.2.0:

我的SpringConfig.xml是:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.0.xsd 
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- Specifying that this project is using annotation based Dependency Injection or IOC -->
    <context:annotation-config />

    <context:component-scan base-package="com.company" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@//URL:PORT/SERVICENAME" />
        <property name="username" value="ID" />
        <property name="password" value="Password" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.company.client.hibernate.domain.Te</value>
                <value>com.company.client.hibernate.domain.TeComment</value>
                <value>com.company.client.hibernate.domain.TeReason</value>
                <value>com.company.client.hibernate.domain.TeStatus</value>
                <value>com.company.client.hibernate.domain.TeType</value>
                <value>com.company.client.hibernate.domain.TeTypeToReasonMapping</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean   id="transactionManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager"
            p:sessionFactory-ref="sessionFactory" />

    <tx:annotation-driven transaction-manager="transactionManager" />

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

    <aop:aspectj-autoproxy />
</beans>

我有两张桌子:原因和评论。

原因表有3列:

  1. ID - 是否使用序列填充PK。
  2. 代码 - 对它有唯一约束,是一个varchar字段。
  3. 描述 - 带文本的varchar
  4. 评论表有4列:

    1. ID - 是否使用序列填充PK。
    2. ReasonCode - 有一个带有原因表的FK。
    3. Order - Integer - 对它和原因码有唯一约束。
    4. 评论 - 带文字的varchar
    5. 我正在为Hibernate和Spring使用注释。

      我的理由域对象有

      private BigDecimal reasonId;
      private String reasonCode;
      private String reasonDescription;
      private List<TeComment> comments;
      
      @Column(name = "REASON_ID", unique = true, nullable = false, precision = 22, scale = 0)
      public BigDecimal getReasonId() {
      
      @Column(name = "REASON_CODE", unique = true, nullable = false, length = 20)
      public String getReasonCode() {
      
      @Column(name = "REASON_DESCRIPTION", nullable = false, length = 1024)
      public String getReasonDescription() {
      
      @OneToMany (mappedBy = "reason")
      public List<TeComment> getComments() {
      

      我的评论域对象有:

      private BigDecimal commentId;
      private String commentDescription;
      private String reasonCode;
      private BigDecimal commentOrder;
      private TeReason reason;
      
      @Column(name = "COMMENT_ID", unique = true, nullable = false, precision = 22, scale = 0)
      public BigDecimal getCommentId() {
      
      @Column(name = "REASON_CODE", nullable = false, length = 20, insertable=false, updatable=false)
      public String getReasonCode() {
      
      @Column(name = "COMMENT_DESCRIPTION", nullable = false, length = 1024)
      public String getCommentDescription() {
      
      @Column(name = "COMMENT_ORDER", nullable = false, precision = 22, scale = 0)
      public BigDecimal getCommentOrder() {
      
      @ManyToOne
      @JoinColumn(name = "REASON_CODE", referencedColumnName = "REASON_CODE")
      public TeReason getReason() {
      

      我也在创建业务服务层并为其创建测试脚本。业务服务层中的两种方法是:

      public List<ReasonDTO> retrieveAllReasonsAsDTO(); 
      public List<CommentDTO> retrieveAllCommentsAsDTO(); 
      

      它们实现为:

      @Autowired
      private TeCommentDAO teCommentDao;
      
      @Autowired
      private TeReasonDAO teReasonDao;
      
      @Override
      @Transactional (propagation=Propagation.REQUIRED, readOnly = true)
      public List<ReasonDTO> retrieveAllReasonsAsDTO() {
          return ConvertDomainDTO.convertTeReasonDomainToDTO_List(teReasonDao.findAll());
      } // retrieveAllReasonsAsDTO
      
      @Override
      @Transactional (propagation=Propagation.REQUIRED, readOnly = true)
      public List<CommentDTO> retrieveAllCommentsAsDTO() {
          Search search = new Search(TeComment.class);
          search.addFetch("reason");
      
          List<TeComment> list = teCommentDao.search(search);
          return ConvertDomainDTO.convertTeCommentDomainToDTO_List(list);
      } // retrieveAllCommentsAsDTO
      

      我的JUNIT测试是:

      List<ReasonDTO> allReasons = businessService.retrieveAllReasonsAsDTO();
      assertEquals(allReasons.size(), beginningReasonSize);
      
      List<CommentDTO> allComments = businessService.retrieveAllCommentsAsDTO();
      assertEquals(allComments.size(), beginningCommentSize);
      

      我遇到的问题是hibernate忽略了&#34; addFetch&#34;并且正在单独检索所有原因。我有点解决了,但不明白为什么会这样。

      有两种解决方案:

      1. 我更改了测试脚本的顺序。因此,我首先检索AllComments,然后检索allReasons,而不是首先检索AllReasons。在这种情况下,内部联接得到尊重,并且不会单独检索原因。
      2. 我在评论业务方法上将事务传播从REQUIRED更改为REQUIRES_NEW。在这种情况下,内部联接得到尊重,并且不会单独检索原因。
      3. 显然,问题与共享事务和检索顺序有关,但我不确定原因。有没有人对我有所了解?

        非常感谢。

0 个答案:

没有答案