0

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>

理由とコメントの 2 つのテーブルがあります。

理由テーブルには 3 つの列があります。

  1. ID - シーケンスを使用して設定された PK です。
  2. コード - それに対して一意の制約があり、varchar フィールドです。
  3. 説明 - テキスト付きの varchar

コメント テーブルには 4 つの列があります。

  1. ID - シーケンスを使用して設定された PK です。
  2. ReasonCode - 理由テーブルを含む FK があります。
  3. 注文 - 整数 - には、それと理由コードに関する一意の制約があります。
  4. コメント - テキスト付きの varchar

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() {

また、ビジネス サービス レイヤーを作成し、そのテスト スクリプトを作成しています。ビジネス サービス層の 2 つのメソッドは次のとおりです。

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);

休止状態が「addFetch」によって決定された内部結合を無視し、すべての理由を個別に取得しているという問題があります。私はそれを解決しましたが、なぜこのように機能しているのかわかりません。

次の 2 つの解決策があります。

  1. テスト スクリプトの順序を変更します。したがって、最初に AllReasons を取得する代わりに、最初に AllComments を取得してから allReasons を取得します。この場合、内部結合が受け入れられ、理由は個別に取得されません。
  2. Comments ビジネス メソッドで、トランザクションの伝播を REQUIRED から REQUIRES_NEW に変更します。この場合、内部結合が受け入れられ、理由は個別に取得されません。

明らかに、問題はトランザクションの共有と取得の順序に関係していますが、その理由はわかりません。誰かが私に洞察を持っていますか?

どうもありがとう。

4

0 に答える 0