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;