1

Spring 3.1.1.RELEASE、Hibernate 4.1.0.Final、JPA 2.0を使用してWARを構築し、JBoss7.1.1.Finalに返信しています。私はこのエンティティにいくつかの怠惰な関連付けがあります…</p>

@GenericGenerator(name = "uuid-strategy", strategy = "uuid.hex")
@Entity
@Table(name = "cb_contract",
    uniqueConstraints = {@UniqueConstraint(columnNames={"OPPORTUNITY_ID","PRODUCT_ID"})}
)
public class Contract implements Serializable {

    …
    @Id
    @Column(name = "ID")
    @GeneratedValue(generator = "uuid-strategy")
    private String id;

    @OneToOne(fetch = FetchType.LAZY, targetEntity = Product.class)
    @JoinColumn(name = "PRODUCT_ID")
    @NotNull
    private Product product;

    @OneToOne(fetch = FetchType.LAZY, targetEntity = Organization.class)
    @JoinColumn(name = "ORGANIZATION_ID")
    @NotNull
    private Organization org;

これらのエンティティを1つのトランザクションメソッドからロードします…</p>

@Transactional
@Service
public class ContractServiceImpl implements ContractService
...

public List<Contract> findContractByOppId(final String oppId)
{
    final Contract contract = new Contract();
    contract.setOpportunityId(oppId);
    return m_contractDao.find(contract);
}   // findContractByOppId

次に、それらを別の@Transactionalメソッドに保存してみます(このプライベートメソッドは@Transactionalパブリックメソッドから呼び出されます)。

@Service
@Transactional
public class UserServiceImpl implements UserService
{
...
private void saveUserContracts(final User user, final Set<Contract> contracts)
{
    if (contracts != null)
    {
        for (final Contract contract : contracts)
        {
            contract.getOrg();
            contract.getProduct();

            final UserContract userContract = new UserContract();
            userContract.setContract(contract);
            userContract.setUser(user);
            userContractDao.save(userContract);
        }   // for
    }   // if
}   // saveUserContracts

ただし、それらを保存しようとすると、以下の例外が発生します。レイジーエンティティをロードするにはどうすればよいですか(Hibernate固有のメソッドではなくJPAを使用することが望ましい)?

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:149)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:195)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
    at org.mainco.subco.organization.domain.Organization_$$_javassist_10.hashCode(Organization_$$_javassist_10.java)
    at org.mainco.subco.ecom.domain.Contract.hashCode(Contract.java:134)
    at java.util.HashMap.put(HashMap.java:372)
    at java.util.HashSet.add(HashSet.java:200)
    at java.util.AbstractCollection.addAll(AbstractCollection.java:305)
    at java.util.HashSet.<init>(HashSet.java:100)
    at org.mainco.subco.user.test.service.UserServiceTest.testAddUser(UserServiceTest.java:116)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

ありがとう、-デイブ

4

1 に答える 1

0

提供された情報に基づいて、少なくとも 3 つのことが間違っていると思います (私の解釈が現実と一致しない場合は訂正してください)。

  • Contract#hashCode()遅延ロードされるプロパティに依存しているようです。hashCodeエンティティがセッションにアタッチされていなくても、すべてのコンテキストで機能する必要がある基本的な方法です。
  • 次のようなことをしているようです: クラス X はトランザクション サービス A を呼び出し、結果を取得して別のトランザクション サービス B に渡します。A が完了すると、すべてのエンティティが切り離されます。メンバーを遅延ロードすることはできません。セッションがある B の内部でも、これらのエンティティは自動的に再接続されません。基本的に、それが例外の理由です。
  • UserServiceTestトランザクションサポートを適切にセットアップしたかどうかはわかりませんが、実際にはわかりません。

できることは、X 自体がトランザクション対応であることを確認することです。この場合、デフォルトで A と B のメソッドが同じトランザクションに参加します。X が完了するまで、エンティティは切り離されません。

于 2013-02-11T18:26:14.540 に答える