2017-04-01 72 views
0

我有多對一的關係單向的,我試圖堅持子實體即SubscriptionEntity也希望它也應該爲我使用級聯堅持父= CascadeType.PERSISTJPA級聯堅持 - 多對一單向

背景有關關係:SubscriptionEntity讓你知道哪些用戶與該業務相關聯,有幾個實體喜歡的狀態和產品,它告訴我們的訂閱狀態,什麼是產品與訂閱關聯。訂閱狀態是一對多的雙向性,因爲訂閱可以在整個會員狀態中保持活動,停用等多種狀態。同樣,訂閱與產品的關係是一對多的雙向,因爲用戶可以訂閱一個產品或超過一個。

我們不能在用戶和訂閱之間進行雙向關聯,因爲用戶可以與許多業務關聯。

public class SubscriptionEntity implements Domain, Serializable 
    { 
     @Column(name = "subscription2user") 
     @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.PERSIST) 
     @JoinColumn(name = "subscription2user") 
     private UserEntity user; 

     @Column(name = "subscription2biz") 
     @ManyToOne(optional = false, fetch = FetchType.LAZY) 
     @JoinColumn(name = "subscription2biz") 
     private BusinessEntity business; 

     @OneToMany(fetch = FetchType.EAGER, mappedBy = "subscription", cascade = CascadeType.PERSIST) 
     private List<ProductSubscriptionEntity> subscribedProducts; 

     @OneToMany(fetch = FetchType.EAGER, mappedBy = "subscription", cascade = CascadeType.PERSIST) 
     private List<SubscriptionStateEntity> state; 
    } 

public class UserEntity implements Domain, Serializable 
{ 
    private static final long serialVersionUID = 755369097357065341L; 

    @Id 
    @Column(name = "user_id") 
    private String id; 

    @Column(name = "user_first_name") 
    private String firstName; 

    @Column(name = "user_last_name") 
    private String lastName; 

    @Column(name = "user_mobile") 
    private BigInteger mobile; 

    @Column(name = "user_password") 
    private String password; 

    @Column(name = "user_create_date") 
    private Date createDate; 

    @OneToOne(cascade = CascadeType.PERSIST) 
    @JoinColumn(name = "user2address") 
    @Column(name = "user2address") 
    private UserAddressEntity address; 
} 

public class SubscriptionStateEntity implements Domain, Serializable 
{ 
    @Column(name = "subscription_state2subscription") 
    @ManyToOne(optional = false) 
    @JoinColumn(name="subscription_state2subscription") 
    protected SubscriptionEntity subscription; 
} 

public class ProductSubscriptionEntity implements Domain, Serializable 
{ 
    @Column(name = "user_product_subscription2subscription") 
    @ManyToOne(optional = false, fetch = FetchType.EAGER) 
    @JoinColumn(name = "user_product_subscription2subscription") 
    private SubscriptionEntity subscription; 
} 

場景:業務已經存在,但用戶是新的,用戶和訂閱之間的關聯也是新的。當我試圖添加新的訂閱獲取低於錯誤。如果用戶已經存在於數據庫中,那麼它工作順利。

void addSubscription(final UserEntity user, final String businessID) 
{ 
    final UserEntity userTemp = this.userDao.readUserByIdOrMobile(user.getId(), user.getMobile()); 
    if (null == userTemp) 
    { 
     user.setId(java.util.UUID.randomUUID().toString()); 
     user.setCreateDate(DateUtil.getDateTimestamp()); 
    } 
    final BusinessEntity business = getBusinessByID(businessID); 
    SubscriptionEntity subscription = new SubscriptionEntity(); 
    subscription.setUser(user); 
    subscription.setBusiness(business); 

    super.getEm().persist(subscription); 
} 

產生的原因: org.apache.openjpa.persistence.EntityExistsException:不能添加或更新 子行:外鍵約束失敗......參考 useruser_id)ON刪除任何行動更新不行動

任何幫助非常感謝。提前致謝。

+0

你確定這是代碼嗎?通常,當您有JoinColumn時,Column不會被使用。將引發註釋異常 – Simon

+0

是的,它的工作代碼我在持續訂閱時遇到異常。 –

+0

如果使用OpenJPA,它可以與JoinColumn一起使用。當我們使用Hibernate時,它將不起作用。 –

回答

0

看起來您沒有在UserEntity實體上提供表和列映射註釋。

由於您沒有設置UserEntity的id,您是否定義了id生成策略?如果您沒有設置id,訂閱和用戶之間就沒有鏈接。

您可以使用以下在UserEntity on id字段中給出的註釋將id生成策略添加爲自動增量。這將在創建時生成ID。

GeneratedValue(strategy = GenerationType.IDENTITY) private String id;

+0

用戶表具有id,firstName,lastName,mobile,emaild,address。 我檢查是用戶通過移動電話號碼已存在,如果如下所示不然後,指派ID新的UUID: 空隙addSubscription(最終UserEntity用戶,最終字符串businessID) { 最終UserEntity USERTEMP = this.userDao.readUserByIdOrMobile(用戶。 getId(),user.getMobile()); (null == userTemp) { user.setId(java.util.UUID.randomUUID()。toString()); user.setCreateDate(DateUtil.getDateTimestamp()); } } –

+0

你可以用UserEntity類代碼更新你的問題嗎? – OTM

+0

用UserEntity更新了問題,感謝您提出問題。 –

0

您沒有爲用戶實體指定任何ID,因爲ID是String,它將創建一個ID爲「」的UserEntity。嘗試爲用戶實體ID添加一些ID生成策略,否則新創建的用戶始終是導致此EntityExistsException的用戶。

附:雙向關聯只是意味着你可以從雙方獲得實體。它與您的業務邏輯沒有任何關係。

+0

我已經更新了我原來的問題,並在原始文章中錯過了以下文字。 user.setId(java.util.UUID.randomUUID()。toString()); –

+0

我們正在避免使用UserEntity和SubscriptionEntity之間的雙向關聯,因爲如果我們通過任何業務拉用戶,那麼由於雙向關聯,它將允許與其他業務關聯的訂閱的可見性以及我們不想公開的。 –

+0

好的,現在我明白你的意思了。如果您嘗試將新用戶設置爲新訂閱,爲何要將用戶傳遞給訂閱? – Simon