是否可以保存引用未保存代理的实体



背景

我的项目中有两个实体。一个被称为"实体",另一个是关系。我用它们来模拟游戏中物体之间的关系。所以在我的数据库中有某种树/层次结构。。。但在我的比赛中情况并非如此。我的实体看起来是这样的。。。
@Entity
@Table(name = "entity")
@Access(AccessType.FIELD)
public class EntityPojo implements Serializable {
@Id public long id;
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Set<RelationshipPojo> relations = new LinkedHashSet<>();
}
@Entity
@Table(name = "relationship")
@Access(AccessType.FIELD)
public class RelationshipPojo {
@Id
public long id;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "entity_id")
public EntityPojo owner;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public Set<EntityPojo> targets = new LinkedHashSet<>();
}

问题

我的一个ingame对象在引用未保存的实体时可能正在保存。想象一下这个场景。。。在我的游戏中,我创建了多个ingame对象和它们的实体pojo。然后其中一个(tile)被保存,但无法获得未保存对象的代理,这会导致ObjectNotFoundException。

var tile = new EntityPojo();
tile.id = 1;
var player = new EntityPojo();
player.id = 2;
var proxy = session.getReference(EntityPojo.class, 2L);     // Reference to unsaved player
var inTileRelation = new RelationshipPojo();
inTileRelation.name = "inTile";
inTileRelation.owner = tile;
inTileRelation.targets.add(proxy);                          // ObjectNotFoundException
tile.relations.add(inTileRelation);
// Tile gets saved before player was saved... 
syncDatabase.save(tile);

问题

为什么会发生这种情况,我该如何预防?是否可以通过代理保存对另一个实体的引用?仅仅通过拥有实体未来将拥有的id?我怎么能做到这一点?在SQL中,我只需删除约束即可插入id本身。。。这在hibernate中可能吗?

正如文档中所述:

在不初始化其数据的情况下获得实体引用

有时被称为延迟加载,在不必加载实体数据的情况下获得对实体的引用的能力非常重要。最常见的情况是需要在实体和另一个现有实体之间创建关联

Book book = new Book();
book.setAuthor( entityManager.getReference( Person.class, personId ) );

上面的工作基于这样的假设,即实体被定义为允许延迟加载,通常通过使用运行时代理在这两种情况下,当应用程序试图以任何需要访问其数据的方式使用返回的代理时,如果给定实体没有引用实际的数据库状态,则稍后将引发异常。

因此,只有当您知道数据库有一个具有指定id的记录,并且您只想在没有实际实体加载的情况下建立关系时,才可以使用entityManager.getReference

最新更新