我正在使用Spring 3.1.1.RELEASE,Hibernate 4.1.0.Final,JPA 2.0构建一个WAR,并回复JBoss 7.1.1.Final。我有这个实体有几个懒惰的关联......
@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;
我从一个交易方法加载这些实体......
@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
然而,在尝试保存它们时,我得到以下例外。如何加载延迟实体(最好使用JPA而不是特定于Hibernate的方法)?
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)
谢谢, - 戴夫
答案 0 :(得分:0)
根据提供的信息,我认为至少有三件事是错的(如果我的解释与现实不符,请纠正我):
Contract#hashCode()
似乎依赖于延迟加载的属性。不要这样做,hashCode
是在每个上下文中都需要工作的基本方法,即使实体没有附加到会话中。UserServiceTest
可能会也可能没有正确设置交易支持,实在说不出来。您可以做的是确保X本身是事务性的,在这种情况下,A和B中的方法默认参与同一事务。在X完成之前,实体不会分离。