2014-10-18 25 views
0

我對Spring/JPA相當陌生,所以這是一個微不足道的問題。只有在不存在@ ManyToOne引用的對象時纔會存在

我有兩個具有多對一關係的實體:Item和ItemType。基本上,ItemType只是表示一組項目的唯一名稱。我使用CrudRepository<Item, Long>來存儲它們。相關代碼如下(getter/setter方法/的equals()/ hashCode()方法略):

@Entity 
public class Item { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 
    @JoinColumn(name = "type_id") 
    private ItemType itemType; 

    public Item() {} 

    public Item(ItemType itemType) { 
     this.itemType = itemType; 
    } 
} 


@Entity 
public class ItemType { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @Column(unique = true, nullable = false) 
    private String name; 

    public ItemType() {} 

    public ItemType(String name) { 
     this.name = name; 
    } 
} 

@Controller 
public class ItemsController { 
    @Autowired private ItemsRepo itemsRepo; 

    @RequestMapping(value = "/item", method = RequestMethod.POST) 
    @ResponseBody 
    public Item addQuestionSet(@RequestBody Item item) { 
     return itemsRepo.save(item); 
    } 
} 

當我插入一個新的項目到數據庫中,我希望它無論從用的ItemType得到type_id給定名稱(如果它已經存在),否則來自新保留的ItemType。

截至目前,我試圖與同類型插入第二個項目時,自然會得到一個異常:

org.hsqldb.HsqlException: integrity constraint violation: unique constraint or index violation 

我大概可以保存一個新的項目進入倉庫前在我的控制器中的樣板檢查。但是這個任務相當通用,我很確定JPA中必須有一個方便的解決方案。

謝謝。

回答

0

看來你是persist()方法上的Item對象而不是merge()方法。我希望它能解決你的查詢。

+0

感謝您的答覆。我從來沒有明確地調用這些,我用CrudRepository的save()方法保存對象。不應該以某種方式從模式中派生save方法嗎?如果我刪除'CascadeType.PERSIST',我得到'org.hibernate.TransientPropertyValueException:對象引用未保存的瞬態實例 - 在沖洗前保存瞬態實例' – SqueezyMo 2014-10-18 20:17:57

+0

你可以發佈你的實體保存代碼嗎? – DeepInJava 2014-10-18 20:28:23

+0

但我沒有一個,我的理解是,Spring根據模式在底層做了些什麼。 http://stackoverflow.com/a/23578842/1815052 – SqueezyMo 2014-10-18 20:51:52

0

我可以看出問題出在你「堅持」時,嘗試用「懶」式。只有當你需要它和EAGER時,你才能得到數據。 我可以給你一個例子,我怎麼辦呢

這是我的班「CentroEstudio」

@Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "idCentroEstudio",nullable=false) 
    private Long idCentroEstudio; 
    @ManyToOne(fetch = FetchType.EAGER,cascade=CascadeType.ALL) 
    @JoinColumn(name = "idTipoCentroEstudio", nullable = false)  
    private TipoCentroEstudio tipoCentroEstudio; 
    @Column(name="nombre",nullable=false) 
    private String nombre; 
    @Column(name="activo",nullable=false) 
    private boolean activo; 

這是我的班「TipoCentroEstudio」

@Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name="idTipoCentroEstudio",nullable=false) 
    private Long idTipoCentroEstudio;  
    @Column(name="descripcion",nullable=false) 
    private String descripcion; 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "tipoCentroEstudio") 
    private Set<CentroEstudio> centroEstudio = new HashSet<CentroEstudio>(0); 

我爲西班牙遺憾在這個例子中,但我是祕魯人,我說西班牙語。 我希望這可以幫助你...

相關問題