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

Java Google genericdao框架使用Maven、Spring和Hibernate执行不必要的选择,java,hibernate,genericdao,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

我正在使用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>
我还创建了一个业务服务层,并为其创建了测试脚本。业务服务层中的两种方法是:

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忽略了addFetch指定的内部连接,并单独检索所有原因。我已经解决了,但不明白为什么会这样

有两种解决方案:

我更改了测试脚本的顺序。因此,我不是先检索AllReasons,而是先检索AllComments,然后检索AllReasons。在这种情况下,内部联接将被接受,并且不会单独检索原因。 我在Comments业务方法中将事务传播从REQUIRED更改为REQUIRED\u NEW。在这种情况下,内部联接将被接受,并且不会单独检索原因。 显然,问题与共享事务和检索顺序有关,但我不确定原因。有人对我有什么见解吗


非常感谢。

这样大的问题很少引起任何人的注意,因为它太长了,尽管我可以证明我错了。您的问题是一个休眠问题,也许您应该关注这个问题?请阅读,谢谢你的建议。问题已经被改写了,试图把它归结为ngRITTY。你已经提供了很多代码在这里,请考虑修改你的问题,包括一个
@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
List<ReasonDTO> allReasons = businessService.retrieveAllReasonsAsDTO();
assertEquals(allReasons.size(), beginningReasonSize);

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