仅当@ ManyToOne引用的对象不存在时才持久存在

时间:2014-10-18 19:48:04

标签: java spring jpa

我是Spring / JPA的新手,所以这有点微不足道。

我有两个具有多对一关系的实体:Item和ItemType。基本上,ItemType只表示一组Items的唯一名称。我使用CrudRepository<Item, Long>来存储它们。相关代码如下(省略getters / setters / 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中获取。{/ p>

截至目前,在尝试插入具有相同类型的第二个项目时,我自然会遇到异常:

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

在将新项目保存到存储库之前,我可能会在控制器中进行样板检查。但是这个任务非常通用,我很确定在JPA中必须有一个方便的解决方案。

感谢。

2 个答案:

答案 0 :(得分:0)

您似乎是Item对象而不是persist()方法的merge()方法。我希望它能解决您的疑问。

答案 1 :(得分:0)

我可以看到问题是当你&#34;坚持&#34;,试试&#34;懒惰&#34;类型。您只能在需要时获取数据并始终获得EAGER。 我可以举个例子来说明我是怎么做的

这是我的班级&#34; CentroEstudio&#34;

   @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;

这是我的班级&#34; TipoCentroEstudio&#34;

   @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);

我很抱歉这个例子中的西班牙语,但我是秘鲁人,我会讲西班牙语。 我希望这可以帮助你...