【问题标题】:Entity manager persist causes unnecessary updates实体管理器持久化导致不必要的更新
【发布时间】:2015-01-27 16:03:59
【问题描述】:

我有以下实体结构。

@Entity
@Table(name = "vertex")
@Inheritance(strategy = InheritanceType.JOINED)
public class Vertex implements Serializable {
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "vertex_edge", joinColumns = {
    @JoinColumn(name = "vertex_id", referencedColumnName = "vertex_id")
}, inverseJoinColumns = {
    @JoinColumn(name = "edge_id", referencedColumnName = "edge_id")
})
/** list of neighbor resources. */
private Collection<Edge> edges= new HashSet<Edge>();

public void setVertex(Vertex neighbourVertex)
{  Edge  edge = new Edge(this, neighbourVertex);
   edges.add(edge);
  }


@Entity
@Table(name = "edge")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "edgeType", discriminatorType =  DiscriminatorType.STRING)
public abstract class Edge implements Serializable {
/**
 * 
 */
private static final long serialVersionUID = 8827162781366388321L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "edge_id", nullable = false)
private long edgeID; 
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "start_vertex_id")
private Vertex start;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "end_vertex_id")
private Vertex end;
}

这是如何保存实体的部分。

EntityManager em = EMFactory.getEM();
        em.getTransaction().begin();
        Vertex vertex1= new Vertex ();
        vertex1.setVertex(new Vertex ());
        em.persist(vertex1);
        em.flush();
        em.getTransaction().commit();
        em.close();

这是输出。我无法理解更新声明。当我持久化大量对象时,这对我来说是一个性能问题。

Hibernate: insert into vertex
Hibernate: insert into edge (end_vertex_id, start_vertex_id, edgeType) values (?, ?, 'edgeType1')
Hibernate: insert into vertex
**Hibernate: update edge set end_vertex_id=?, start_vertex_id=? where edge_id=?**
Hibernate: insert into vertex_edge(vertex_id, edge_id) values (?, ?)

Jpa 配置

    <persistence-unit name="DBService"
    transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="javax.persistence.jdbc.user" value="user" />
        <property name="javax.persistence.jdbc.password" value="password" />
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
        <property name="javax.persistence.jdbc.url" value="url of database" />

        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.jdbc.batch_size" value="100" />
            value="false" />
    </properties>

</persistence-unit>

【问题讨论】:

  • 您也可以添加您的 jpa 配置吗?
  • 添加了 Jpa 配置

标签: java hibernate jpa entitymanager


【解决方案1】:

我猜在你的代码中当你保存你的edge 对象时你会创建一个YouredgeEntity.setSomeProperty(..) 这就是当您保存或获取实体之后休眠的工作方式,该实体留在会话中,或者我们说附加到会话,并且当您执行一些setting hibernate make updating

保存对象时显示您的代码以获得更多帮助

【讨论】:

  • 我添加了保存部分。保存实体后,我没有设置任何新属性。
【解决方案2】:

你的映射很奇怪,因为你有:

  • 带有顶点参考的边
  • 一个与边多对多关联的顶点,因此还有一个额外的 vertex_edge 链接表

我认为您需要将 Edge 更改为:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "start_vertex_id")
private Vertex start;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "end_vertex_id")
private Vertex end;

和顶点到:

@OneToMany(mappedBy="start")
private Set<Edges> startEdges = new HashSet<Edge>();

@OneToMany(mappedBy="end")
private Set<Edges> endEdges = new HashSet<Edge>();

只要确保你同步关联的双方。

【讨论】:

  • 我在 Vertex 类中添加了 setVertex 函数。它实现了 item1 和 item 2。
  • 查看我更新的答案,了解您需要如何重构映射。
  • addEdge 函数错误。您正在向边缘集合添加顶点。
  • 我把它拿出来了。您应该提供一种方法来设置关联的双方并决定如何处理这些关系。无论如何,您之前的映射是错误的,因此您可能对让 Edge 和 Vertex 实体和 EdgeVertex 实体来链接前两个实体感兴趣。祝你好运。
猜你喜欢
  • 2013-02-27
  • 1970-01-01
  • 2014-05-13
  • 2014-10-18
  • 2022-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多