Java Hibernate:使用EntityManager插入更新

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

我有一个在一个字段上具有唯一约束的表,我想设置Hibernate EntityManager,以便它仅在没有此类记录时插入新记录,并以其他方式更新

我的表格POJO如下所示:

@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=?