将对象保存在数据库中(如果它尚不存在)(Hibernate& Spring)

时间:2013-01-14 15:11:17

标签: spring hibernate

我正在使用Hibernate / Spring应用程序管理一些电影。

班级电影与班级类型有很多关系。 这两个类都使用GeneratedValue注释生成了id。

使用@Cascade(CascadeType.SAVE_UPDATE)通过影片对象保存流派 我对类型的类型属性(这是它的名称;例如“幻想”)设置了一个独特的约束。

我现在要做的是让Hibernate检查是否已经有类型为“Fantasy”的类型,如果有,请使用该类型的id而不是尝试插入新记录。 (后者显然会引发错误)

最后我需要的是像select-before-update之类的东西,但更像是select-before-save。

Hibernate中有这样的功能吗?

一些代码:

电影课

@Entity
public class Movie {

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

private String name;

@Lob
private String description;

@Temporal(TemporalType.TIME)
private Date releaseDate;

@ManyToMany
@Cascade(CascadeType.SAVE_UPDATE)
private Set<Genre> genres = new HashSet<Genre>();

.... //other methods

类型课

@Entity
public class Genre {

@Column(unique=true)
private String type;

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

....//other methods

2 个答案:

答案 0 :(得分:5)

你可能会过度思考这个问题。任何select-before-update / select-before-save选项将导致2个DB往返,第一个用于select,第二个用于插入(如果需要)。

如果你知道从一开始就不会有很多类型,那么你在大多数时间里都可以通过一些方法在1 RT中完成这项工作:

  1. Hibernate二级缓存可以容纳很多(如果不是全部)类型,在检查存在时会导致简单的哈希表查找(假设单个节点)。
  2. 您可以假设您的所有类型都已存在,请使用session.load(),并在引用尚未存在的类型时因行未找到异常而处理新插入。
  3. 但实际上,除非您谈论大量交易,否则在保存/更新之前进行简单的预查询不会影响您的性能。

答案 1 :(得分:3)

我还没有在Hibernate select-before-update / select-before-save中听说过这样的功能 在这种情况下,您应该将Hibernate视为JDBC。

首先,如果你想知道你是否有这样的类型,你应该查询它。

如果你这样做。然后SAVE_UPDATE在您将其添加到电影时不会创建新的。 如果你不这样做,Hibernate将在数据库中创建一个新的Genre行,并为你添加连接到many_to_many表。