为了保持传输的数据很小,我在数据库中为我的文件创建了两个实体。 fileheader
保留有关文件和fileblob
的一般信息,包括fileId
和blob。通常,我只需要询问一般fileinformations
。
所以我需要懒惰地加载fileblobs
。
正如我在this discussion和that discussion.中所了解到的,这可以通过optional = false
来实现。它非常适合懒惰地加载fileblobs
。不幸的是,它会影响级联保存。
所以这是我在Fileh.class
中对blob的属性:
@OneToOne(mappedBy = "fileh", targetEntity = Fileblob.class, fetch = FetchType.LAZY, optional = false)
@org.hibernate.annotations.Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK })
private Fileblob fileblob;
如果我现在保存附加fileh
的{{1}},则会抛出此错误:
org.hibernate.id.IdentifierGenerationException:生成null id for:class Fileblob
如果我从id-generation策略“identity”切换到“increment”,则抛出此错误:
fileblob
ERROR SqlExceptionHelper:147 - Cannot add or update a child row: a foreign key constraint fails (`CORE`.`FILEBLOB`, CONSTRAINT
FOREIGN KEY(FKFILEBLOB412557
)参考ID
(FILEH
)) 查询是:插入CORE。ID
(FILEBLOB
,FILEBLOB
)值(?,?)
因此生成id时出现问题... 如果我现在关闭通过级联保存我的属性看起来像这样。
ID
为了现在保存,我必须致电
@OneToOne(mappedBy = "fileh", targetEntity = Fileblob.class, fetch = FetchType.LAZY, optional = false)
private Fileblob fileblob;
这不仅仅是persistentSession.saveOrUpdate(fileh);
persistentSession.saveOrUpdate(fileblob);
应该做的吗?
为什么这适用于“手动级联”但不能自动生效?
P.s。:在CascadeType.SAVE_UPDATE
fileblob.class
答案 0 :(得分:1)
首先,我会使用JPA级联而不是hibernate:
@OneToOne(mappedBy = "fileh", fetch = FetchType.LAZY, optional = false)
private Fileblob fileblob;
Fileblob,我认为没有那些生成器和东西你的配置可以更简单一些(假设id实际上应该是指向Fileh.id的外键)。
@Column(name="`ID`", nullable=false, unique=true)
@Id
private int filehId;
@JoinColumn(name = "id", referencedColumnName = "id")
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@MapsId
private Fileh fileh;
答案 1 :(得分:1)
我遇到了完全相同的问题并试图解决它好几天了!事实证明这个问题已经在Hibernate的bug系统中撒谎超过2年了!
虽然这里的答案确实有助于解决问题,但我们不得不放弃使用来自父实体的Persist Cascade(反面,也包括 mappedBy 定义的那一面)
请参阅此链接:https://hibernate.atlassian.net/browse/HHH-9670
如果您想将延迟加载应用于OneToOne关系,并且能够像往常一样执行Persist级联,请发表评论以表明您对该问题的关注!