实体管理器持久导致不必要的更新

时间:2015-01-27 16:04:00

标签: java hibernate jpa entitymanager

我有以下实体结构。

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

2 个答案:

答案 0 :(得分:0)

我想在您的代码中保存edge对象后,您会YouredgeEntity.setSomeProperty(..) 这是hibernate在保存或获取实体之后如何工作实体保留在会话中,或者我们说是附加到会话以及当你执行setting hibernate make updating时。

保存对象时显示代码以获取更多帮助

答案 1 :(得分:0)

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

  • 带有顶点引用的边
  • 具有与Edge的多对多关联的顶点,因此附加的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>();

请确保同步关联的两面。