2014-10-18 57 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); 

我为西班牙遗憾在这个例子中,但我是秘鲁人,我说西班牙语。 我希望这可以帮助你...

相关问题