Java Hibernate:使用EntityManager插入更新
我有一个在一个字段上具有唯一约束的表,我想设置Hibernate EntityManager,以便它仅在没有此类记录时插入新记录,并以其他方式更新 我的表格POJO如下所示:Java Hibernate:使用EntityManager插入更新,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我有一个在一个字段上具有唯一约束的表,我想设置Hibernate EntityManager,以便它仅在没有此类记录时插入新记录,并以其他方式更新 我的表格POJO如下所示: @Entity @Table(name = "links", uniqueConstraints = { @UniqueConstraint(columnNames = "link", name = "uk_link") }) public class Link { private lon
@Entity
@Table(name = "links", uniqueConstraints = {
@UniqueConstraint(columnNames = "link", name = "uk_link")
})
public class Link {
private long linkId;
private String link;
private String data;
private String metadata;
private List<Result> results;
@Id
@Column(name="link_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
public long getLinkId() {
return linkId;
}
public void setLinkId(long linkId) {
this.linkId = linkId;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public String getMetadata() {
return metadata;
}
public void setMetadata(String metadata) {
this.metadata = metadata;
}
@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "link")
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
@Override
public String toString() {
return "Link [linkId=" + linkId + ", link=" + link + ", data=" + data + ", metadata=" + metadata + "]";
}
public boolean isDataEquals(String data) {
if (this.data == null) {
if (data != null)
return false;
} else if (!this.data.equals(data))
return false;
return true;
}
public boolean isMetadataEquals(String metadata) {
if (this.metadata == null) {
if (metadata != null)
return false;
} else if (!this.metadata.equals(metadata))
return false;
return true;
}
}
在Spring日志中,我看到了一个额外的选择:
Hibernate: select link0_.link_id as link_id1_0_, link0_.data as data2_0_, link0_.link as link3_0_, link0_.metadata as metadata4_0_ from links link0_ where link0_.link=?
Hibernate: select link0_.link_id as link_id1_0_1_, link0_.data as data2_0_1_, link0_.link as link3_0_1_, link0_.metadata as metadata4_0_1_, results1_.link_id as link_id1_1_3_, results1_.text_id as text_id2_1_3_, results1_.link_id as link_id1_1_0_, results1_.text_id as text_id2_1_0_, results1_.found as found3_1_0_, results1_.level as level4_1_0_ from links link0_ left outer join results results1_ on link0_.link_id=results1_.link_id where link0_.link_id=?
Hibernate: update links set data=?, link=?, metadata=? where link_id=?
我猜,这是因为我使用了merge函数,但是如果我在合并对象之前没有搜索对象id,合并将尝试插入对象而不是更新它。有没有一种方法可以在不首先测试的情况下更新对象
还有一个无关的问题,SQL看起来非常混乱。所有这些
link0\uu。link\u id作为link\u id 1\u 0\uu
,它们可以被抑制吗 额外的连接是您懒惰的一对多关系的结果。除了链接本身的select之外,还会执行一个额外的select语句来加载集合(这是著名的N+1问题的根源)
而且,对于更新之前执行的选择,当实体被分离时,hibernate似乎是保持的方式。如果您想避免它,您应该使用它的配置(有一个属性)或自己编写一个更新查询。您也可以尝试避免Spring分离Hibernate实体。这方面有什么改进吗?没有,我暂时不考虑Hibernate,而是切换回模板
Hibernate: select link0_.link_id as link_id1_0_, link0_.data as data2_0_, link0_.link as link3_0_, link0_.metadata as metadata4_0_ from links link0_ where link0_.link=?
Hibernate: select link0_.link_id as link_id1_0_1_, link0_.data as data2_0_1_, link0_.link as link3_0_1_, link0_.metadata as metadata4_0_1_, results1_.link_id as link_id1_1_3_, results1_.text_id as text_id2_1_3_, results1_.link_id as link_id1_1_0_, results1_.text_id as text_id2_1_0_, results1_.found as found3_1_0_, results1_.level as level4_1_0_ from links link0_ left outer join results results1_ on link0_.link_id=results1_.link_id where link0_.link_id=?
Hibernate: update links set data=?, link=?, metadata=? where link_id=?