2

現在、次の例外が原因で、遅延読み込みが双方向のエンティティ関係で機能しないという問題が発生しています。

    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: sample.Person.sent, no session or session was closed
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:394)
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:386)
at org.hibernate.collection.internal.AbstractPersistentCollection.readElementExistence(AbstractPersistentCollection.java:161)
at org.hibernate.collection.internal.PersistentBag.contains(PersistentBag.java:256)
at sample.EmailTest.testTest(EmailTest.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:169)
at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:158)

次のサンプル エンティティ クラスがあります。

Eメール

@Entity
public class Email {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String subject;

@ManyToOne(fetch = FetchType.EAGER)
private Person sender;

@ManyToMany(fetch = FetchType.EAGER)
private List<Person> recipients;

... setters/getters/constructors/equals/hashcode

@Entity
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(unique = true)
private String name;

@OneToMany(mappedBy = "sender")
private List<Email> sent;

@ManyToMany(mappedBy = "recipients")
private List<Email> received;

... setters/getters/constructors/equals/hashcode

次のリポジトリ:

メールリポジトリ

import org.springframework.data.repository.CrudRepository;

public interface EmailRepository extends CrudRepository<Email, Long> {
}

人物リポジトリ

import org.springframework.data.repository.CrudRepository;

public interface PersonRepository extends CrudRepository<Person, Long> {
}

persistence.xml:

<persistence-unit name="unit_test">
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
        <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:spring" />
        <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
        <property name="hibernate.connection.username" value="sa" />
        <property name="hibernate.connection.password" value="" />

        <property name="hibernate.hbm2ddl.auto" value="create-drop" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.use_sql_comments" value="true" />
        <property name="hibernate.cache.use_second_level_cache" value="false"/>
        <property name="hibernate.cache.use_query_cache" value="false"/>
    </properties>
</persistence-unit>

Spring application_context.xml

<jpa:repositories base-package="sample" />

<jdbc:embedded-database id="dataSource" type="HSQL" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="true" />
            <property name="database" value="HSQL" />
        </bean>
    </property>
    <property name="persistenceUnitName" value="unit_test" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

例外を生成するテスト コードは次のとおりです。

@ContextConfiguration(locations={"/application_context.xml"})
public class EmailTest extends AbstractTestNGSpringContextTests{

    @Autowired
    private EmailRepository emailRespository;

    @Autowired
    private PersonRepository personRepository;

    private Long fredId;

    @BeforeMethod
    public void setUp() {
        Person john = new Person("John");
        john = personRepository.save(john);
        Person fred = new Person("Fred");
        fred = personRepository.save(fred);
        Person julio = new Person("Julio");
        julio = personRepository.save(julio);

        Email mail = new Email("subject", john, Lists.newArrayList(john, fred, julio));
        emailRespository.save(mail);

        fredId = fred.getId();
    }

    @Test
    @Transactional
    public void testTest() throws Exception{
        Person fred = personRepository.findOne(fredId);
        List<Email> sent = fred.getSent();
        List<Email> received = fred.getReceived();

        sent.contains(null);
        received.contains(null);

        int i = 0;
    }
}

保存と検索は正常に機能しているように見えますが、メソッドが @Transactional であっても、セッションが閉じられているため、遅延ロードされたコレクションは機能しません。他のほぼ同一のサンプルが見られるため、明らかに何かが欠けています。

編集: fetch = FetchType.EAGER を Email エンティティに追加しましたが、変更はありません。

4

1 に答える 1

0

何が Hibernate セッションを閉じているのかわかりませんが、fetch=FetchType.EAGER以下のマッピングに追加してみてください:

@ManyToOne
private Person sender;

@ManyToMany
private List<Person> recipients;
于 2012-12-29T01:05:39.600 に答える