Java Hibernate OneTONE:强制在可选=false或级联之间进行选择?
为了使传输的数据保持较小,我在数据库中为我的文件创建了两个实体。Java Hibernate OneTONE:强制在可选=false或级联之间进行选择?,java,hibernate,jpa,orm,Java,Hibernate,Jpa,Orm,为了使传输的数据保持较小,我在数据库中为我的文件创建了两个实体。fileheader用于保存有关文件和fileblob的一些常规信息,包括fileId和blob。通常,我只需要询问常规文件信息 因此,我需要缓慢地加载文件blob 正如我在中了解到的,这可以通过optional=false实现。它非常适合于延迟加载文件blob。不幸的是,它会影响级联保存 下面是blob的Fileh.class中的我的属性: @OneToOne(mappedBy = "fileh", targetEntity =
fileheader
用于保存有关文件和fileblob
的一些常规信息,包括fileId
和blob。通常,我只需要询问常规文件信息
因此,我需要缓慢地加载文件blob
正如我在中了解到的,这可以通过optional=false
实现。它非常适合于延迟加载文件blob
。不幸的是,它会影响级联保存
下面是blob的Fileh.class
中的我的属性:
@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;
如果现在使用附加的fileblob
保存fileh
,将引发此错误:
org.hibernate.id.IdentifierGenerationException:生成空id
for:类Fileblob
如果我从id生成策略“identity”切换到“increment”,则会引发此错误:
FKFILEBLOB412557
外键(ID
)引用FILEH
(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);
这不仅仅是CascadeType.SAVE\u UPDATE
应该做的吗?
为什么这适用于“手动级联”,而不是自动级联
注:为了完成我的示例,请参见fileblob.class
@PrimaryKeyJoinColumn
@OneToOne(targetEntity=Fileh.class, fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
@JoinColumns({ @JoinColumn(name="`ID`", referencedColumnName="`ID`", unique=true, nullable=false) })
private Fileh fileh;
@Column(name="`ID`", nullable=false, insertable=false, updatable=false, unique=true)
@Id
@GeneratedValue(generator="FILEBLOB_FILEHID_GENERATOR")
@org.hibernate.annotations.GenericGenerator(name="FILEBLOB_FILEHID_GENERATOR", strategy="foreign", parameters=@org.hibernate.annotations.Parameter(name="property", value="fileh"))
private int filehId;
首先,我将使用JPA级联而不是hibernate级联:
@OneToOne(mappedBy = "fileh", fetch = FetchType.LAZY, optional = false)
private Fileblob fileblob;
还有Fileblob,我认为如果没有这些生成器和东西,您的配置可能会简单一些(假设id实际上应该是指向Fileh.id的外键)
我遇到了完全相同的问题,并试图解决了好几天!事实证明,这是一个在Hibernate的bug系统中存在了2年多的问题强> 虽然这里的答案确实有助于解决这个问题,但我们不得不放弃使用来自父实体的持久级联(相反的一面,也是定义了mappedBy的一面) 请参阅此链接:
如果您想对OneTONE关系应用延迟加载,并且能够像往常一样进行持久级联,请留下评论以表示您对该问题的关注 为了清楚起见,Fileblob.id是否应该与Fileh.id相同?是的,共享主键Hi Maciej,谢谢您的回答!如果我切换到JPA级联,它不是级联,如果我只保存fileheader,数据库中就会缺少fileblob。我是否遗漏了其他内容?如何在保存之前组装实体?还要检查update@Column(name=“
ID
”,nullable=false,unique=true),我调用setters-viceverca:fileh.setfileblob(fileblob)和fileblob.setfileh(fileh)。@Column已按您所考虑的方式更新。请尝试仅设置此端:fileblob.setfileh(fileh)
并保存blob实体saveOrUpdate(fileblob)
,不幸的是,这只是相同的行为。我担心JPA级联没有影响,我只是想知道为什么…谢谢你的回答,也在bug的评论中留下了一些话
@OneToOne(mappedBy = "fileh", fetch = FetchType.LAZY, optional = false)
private Fileblob fileblob;
@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;