首页 > 解决方案 > 在更新其父级时防止休眠选择子级?

问题描述

问题

当我更新我的父类时,休眠会在触发更新之前选择它的所有子类。这只发生在我们添加尚未在数据库中持久化的新子代时。Hibernate一一选择那些孩子,非常……非常慢。

批处理已启用并适用于正常的插入、更新和删除。我给了孩子一个版本,它会以某种方式被忽略。

select * from identity...
select * from identity...
select * from identity...
select * from identity...
insert .... into identity...
update chunk set ....

问题

有没有办法让休眠批处理这些选择或实现一些其他机制,其中休眠只检查添加的孩子是否是新的而不先从数据库中选择它?

我基本上想摆脱那些“一个接一个”的选择。很高兴我能得到任何帮助。

我的课程

当我更新包含多个尚未在数据库中的身份( inChunk )的块时......它会尝试确定它们是否在数据库中,这会导致每个孩子选择一个来过滤那些需要插入的孩子。 ..我如何防止那些选择?我仍然想保持级联。

@Entity
@Access(AccessType.FIELD)
@SQLInsert(sql = "insert into identity(tag, typeID, id, version) values(?,?,?,?) ON DUPLICATE KEY UPDATE id = VALUES(id), tag = values(tag), typeID = values(typeID), version = values(version)")
@SelectBeforeUpdate(value = false)
public class Identity extends Component {

    @Id public long id;
    public String tag;
    public String typeID;

    @Version public long version;
}

@Entity
@Table(name = "chunk", uniqueConstraints = {@UniqueConstraint(columnNames={"x", "y"})}, indexes = {@Index(columnList = "x,y")})
@Access(value = AccessType.FIELD)
@SelectBeforeUpdate(false)
public class Chunk extends HibernateComponent {

    public int x;
    public int y;
    public Date createdOn;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(FetchMode.JOIN)
    @BatchSize(size = 50)
    public Set<Identity> inChunk = new LinkedHashSet<>();
}

标签: javaspringhibernatejpa

解决方案


单向一对多关联 - 不是好的做法。我建议在类中定义多对一关联Identity,然后将mappedBy属性添加到字段上的@OneToMany注释中inChunk,然后Chunk.inChunk在添加新子项之前获取关联。

@Entity
@Access(AccessType.FIELD)
@SQLInsert(sql = "insert into identity(tag, typeID, id, version) values(?,?,?,?) ON DUPLICATE KEY UPDATE id = VALUES(id), tag = values(tag), typeID = values(typeID), version = values(version)")
@SelectBeforeUpdate(value = false)
public class Identity extends Component {

    @Id public long id;
    public String tag;
    public String typeID;

    @Version public long version;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "chunk_id") // I suppose the Chunk entity has id
    public Chunk chunk;
}

@Entity
@Table(name = "chunk", uniqueConstraints = {@UniqueConstraint(columnNames={"x", "y"})}, indexes = {@Index(columnList = "x,y")})
@Access(value = AccessType.FIELD)
@SelectBeforeUpdate(false)
public class Chunk extends HibernateComponent {

    public int x;
    public int y;
    public Date createdOn;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "chunk")
    @Fetch(FetchMode.JOIN)
    @BatchSize(size = 50)
    public Set<Identity> inChunk = new LinkedHashSet<>();
}

推荐阅读