2017-07-14 62 views
0

我有兩個實體,TypeTypeValue。每個Type可以有幾個TypeValue。在試圖保留新的TypeValue時,出現數據庫錯誤Type已存在(這是正確的,但我不想再添加它,我只想添加一個新的'TypeValue')。我有類似的類沒有IdClass正在工作,所以我假設@IdClass定義是錯誤的或我忘了定義的東西,以便所引用的對象不更新。如何防止在使用@IdClass時保存被引用實體?

如何防止被推薦實體Type在使用@IdClassTypeValue的保存?

類定義:

@Entity 
@Table(name = "TYPE", schema = "VOC") 
public class Type implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "TYPEID") 
    private String typeID; 

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

    @OneToMany(mappedBy = "type") 
    private List<TypeValue> listTypeValue; 

    // constructor, getter, setter, equals, hashcode, ... 
} 

@Entity 
@IdClass(TypeValueID.class) 
@Table(name = "TYPE_VALUE", schema = "VOC") 
public class TypeValue implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @ManyToOne 
    @JoinColumn(name = "TYPEID") 
    @ForeignKey(name = "TYPEVALUE_FK") 
    private Type type; 

    @Id 
    @Column(name = "VALUE") 
    private String value; 

    // constructor, getter, setter, equals, hashcode, ... 
} 

public class TypeValueID implements Serializable { 
    private static final long serialVersionUID = 1L; 

    String type; 
    String value; 

    // equals, hashcode 
} 

使用示例:

Type type = ... // get existing type with typeID "DETAIL" 

Session session = sessionFactory.getCurrentSession(); 
TypeValue newTypeValue = new TypeValue(type, "new value"); 
session.save(newTypeValue); 
session.flush(); 

拋出的異常:

SEVERE: Servlet.service() for servlet [spring] in context with path [/project] threw exception [Request processing failed; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause 
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "type_pkey" 
    Detail: Key (typeid)=(DETAIL) already exists. 
     at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2455) 
     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2155) 
     ... 

回答

0

TypeValueID類的type屬性是錯誤的,類應該是這樣的:

public class TypeValueID implements Serializable { 
    private static final long serialVersionUID = 1L; 

    Type type; 
    String value; 

    // equals, hashcode 
} 

JPA Persistence API 2.1 documentation狀態:

在主鍵類的字段或屬性的名稱和實體的主關鍵字段或屬性必須對應,並且它們的類型必須根據第 段2.4中指定的規則匹配,「Pri瑪麗鍵和實體身份「以及第2.4.1節」與導出身份相對應的主鍵「。

這適用於這種情況的規則是:

如果複合主鍵類被表示爲一個id類,主鍵字段或屬性的在主鍵類 名稱和 這些id類映射到的實體類必須與 相對應,且它們的類型必須相同。

0

請改變你的字符串TYPEID爲int或長。然後使用@GeneratedValue進行自動遞增。

@Id 
@GeneratedValue(strategy= GenerationType.AUTO) 
private int typeID ; 

檢查這個例子

@Entity 
@Table(name = "USERS") 
@Proxy(lazy = false) 
public class User { 

@Id 
@GeneratedValue(strategy= GenerationType.AUTO) 
private int uID ; 

private String uName ; 
private String uEmail ; 
private String uPassword; 

@OneToMany(cascade=CascadeType.ALL,fetch = FetchType.EAGER) 
private List<Reminder> uReminders = new ArrayList<>(); 

下一個實體

@Entity 
@Proxy(lazy = false) 
public class Reminder { 

@Id 
@GeneratedValue(strategy= GenerationType.AUTO) 
private int reminderID ; 

private Date reminderDate ; 
private String reminderDescription ; 
+0

我(當前)不允許使用代理鍵,所以我被自然鍵卡住了,在這種情況下,它是一個字符串。但否則這將是一個解決方案。 – Zwie

0

您已經定義與@Id外鍵列。

@Id 
    @ManyToOne 
    @JoinColumn(name = "TYPEID") 
    @ForeignKey(name = "TYPEVALUE_FK") 
    private Type type; 

因此它期望在「類型」列中具有唯一的值。希望這可能有所幫助。

+0

我知道,但它是Type和TypeValue的組合鍵,所以組合應該是唯一的。此外,我有類似的類(使用組合鍵和引用另一個)沒有IdClass註釋正在工作。 – Zwie

相關問題