-1

進一步說進入休眠我已經在下列情況下跌跌撞撞: 我有一個@Entity人@Entity中的@Transactional不起作用?

@Entity 
@Table(name = "PERSON") 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue(value="person") 
public class Person implements PersonInterface{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "USER_ID") 
    protected Integer id; 

    @Column(name = "NAME") 
    protected String name; 

    @ElementCollection 
    @Formula("(SELECT groupId FROM PERSON_GROUPS WHERE id = id") 
    protected List<Integer> groups = new ArrayList<>(); 

    @Override 
    public Integer getId() { 
     return id; 
    } 

    @Override 
    public Collection<Integer> getGroups(){ 
     return groups; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 
} 

這是兩個部分,可變和不可變分裂:

@Entity 
@DiscriminatorValue("mutableperson") 
@Transactional 
public class MutablePerson extends Person implements MutablePersonInterface{ 

    @Override 
    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public void setId(Integer id) { 
     this.id = id; 
    } 

    @Override 
    public void setGroups(List<Integer> groupIds) { 
     this.groups = groupIds; 
    } 

    public void excludeFromGroup(Integer groupId){ 
     Hibernate.initialize(this.groups); 
     this.groups.remove(groupId); 
    } 
} 

現在,當我嘗試調用類似:

Session session = sessionFactory.openSession(); 
MutablePerson personFromDb = (MutablePerson) personService.getMutablePersonById(0); 
personFromDb.excludeFromGroup(group1.getId()); 
session.saveOrUpdate(personFromDb); 

我得到一個異常:

Exception in thread "main" org.hibernate.HibernateException: collection is not associated with any session 
at org.hibernate.collection.internal.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:704) 
at org.hibernate.Hibernate.initialize(Hibernate.java:65) 
at com.studytrails.tutorials.springhibernatejpa.MutablePerson.excludeFromGroup(MutablePerson.java:57) 
at com.studytrails.tutorials.springhibernatejpa.TestSpringHibernateJpa.main(TestSpringHibernateJpa.java:48) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

這告訴我,那個MutablePerson類的@Transactional註釋實際上並不工作,而Hibernate沒有創建一個事務。

這裏的這一位我的Spring配置:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jpaDialect" ref="jpaDialect" /> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

至於我可以從Hibernate的文檔和例子說,這個配置是正確的,它應該工作,但事實並非如此。我在這裏想念另一個Hibernate的細微差別嗎?

P.S.我知道我可以在DAO或Service類中做到這一點,但不幸的是我必須使用現有的API,它與實體的可變半部分中的組一起工作。

+0

請加上'personService.getMutablePersonById'方法的問題代碼。 –

+5

您必須重新考慮設計,它不是一個在實體級別具有事務性的良好實踐,它應該位於業務級別或由spring管理的最大存儲庫級別。 這裏您註釋了實體級別的Transactional以及哪些實體生命週期不會由Spring管理。所以它必然會失敗。 給你一個設計思路,看看你如何適應乾淨 –

+0

@RohanSRaju好的,thx,如果沒有辦法讓它工作,重新設計是不可避免的。 –

回答

0

實體不由Spring管理。它們是通過休眠或手動創建的數據庫操作產品,以保存日期。因此@Transactional註解將不起作用,因爲這不是一個彈簧管理bean。

Spring事務性上下文包裝Spring彈出的託管bean並對其執行操作。它不能包裝非彈簧豆

可能的解決方案 理想地爲服務層或至少Jpa Repository/Dao層移動事務上下文。

+0

好吧,這是有道理的,我忘了@Transactional是Spring API,而不是Hibernate。 –

+0

事情是,在一個對象集合上以類似的方式工作不會產生異常。 如果我將代碼更改爲列表 groups = new ArrayList <>();'用@ ManyToMany'和適當的'@ JoinTable'映射,調用類似'groups.remove(groupId);'的方式工作,更新所需的實體。 這是'@ Formula'註釋如何工作的細節? 「@ Formula」註解字段是否可寫? –

相關問題