Hibernate 一对零或一映射。异常:试图从 null 一对一分配 id 属性?
Hibernate one to zero or one mapping. Exception: attempted to assign id from null one-to-one property?
我按照@Tony 在Hibernate one to zero or one mapping 中回答的那样做。
我有一个 class FileMeta
.
@Entity
@Inheritance
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
@DiscriminatorValue("FileMeta")
public class FileMeta {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
...SOME ATTRIBUTES...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_GARBAGE")
@NotFound(action = NotFoundAction.IGNORE)
protected Garbage garbage;
@Enumerated(EnumType.ORDINAL)
private FileT type;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_SHARE")
@NotFound(action = NotFoundAction.IGNORE)
private Share share;
...METHODS...
}
还有一个classShare
.
@Entity
public class Share {
@Id
@GeneratedValue(generator = "shareForeignGenerator")
@GenericGenerator(
name = "shareForeignGenerator",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "fileMeta")
)
private Long id;
...SOME ATTRIBUTES...
@OneToOne(mappedBy = "share")
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
private FileMeta fileMeta;
...METHODS...
}
当我试图用 Share
填充我的 FileMeta
时:
Share share = new Share();
share.setFileMeta(fileMeta);
fileMeta.setShare(share);
fileMetaRepository.save(fileMeta);
我收到异常:attempted to assign id from null one-to-one property
我跟进了Hibernate
。并注意到,在 generator
方法中,associatedObject
根本不是我给定的 Share
对象,而是 EventSource
[= 实例化的新 Share
对象34=]
在DefaultMergeEventListener.java
、
if ( copyCache.containsKey( entity ) ) {
persister.setIdentifier( copyCache.get( entity ), id, source );
}
else {
( (MergeContext) copyCache ).put( entity, source.instantiate( persister, id ), true ); //before cascade!
}
copyCache
感知到 entity
(即我给定的 Share
对象)不在 copyCache
中,并实例化了一个新的 Share
对象,它显然没有 FileMeta
参考。
我完全糊涂了。
问题的评论中提到了解决方案。为方便起见,在下面给出。
您可以使用 @OneToOne(optional = true)
或简单地使用 @OneToOne
因为 optional
的默认值是 true
.
如果要强制执行 1 对 1 关系,请指定 @OneToOne(optional = false)
。
我按照@Tony 在Hibernate one to zero or one mapping 中回答的那样做。
我有一个 class FileMeta
.
@Entity
@Inheritance
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
@DiscriminatorValue("FileMeta")
public class FileMeta {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected long id;
...SOME ATTRIBUTES...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_GARBAGE")
@NotFound(action = NotFoundAction.IGNORE)
protected Garbage garbage;
@Enumerated(EnumType.ORDINAL)
private FileT type;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "FK_SHARE")
@NotFound(action = NotFoundAction.IGNORE)
private Share share;
...METHODS...
}
还有一个classShare
.
@Entity
public class Share {
@Id
@GeneratedValue(generator = "shareForeignGenerator")
@GenericGenerator(
name = "shareForeignGenerator",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "fileMeta")
)
private Long id;
...SOME ATTRIBUTES...
@OneToOne(mappedBy = "share")
@PrimaryKeyJoinColumn
@NotFound(action = NotFoundAction.IGNORE)
private FileMeta fileMeta;
...METHODS...
}
当我试图用 Share
填充我的 FileMeta
时:
Share share = new Share();
share.setFileMeta(fileMeta);
fileMeta.setShare(share);
fileMetaRepository.save(fileMeta);
我收到异常:attempted to assign id from null one-to-one property
我跟进了Hibernate
。并注意到,在 generator
方法中,associatedObject
根本不是我给定的 Share
对象,而是 EventSource
[= 实例化的新 Share
对象34=]
在DefaultMergeEventListener.java
、
if ( copyCache.containsKey( entity ) ) {
persister.setIdentifier( copyCache.get( entity ), id, source );
}
else {
( (MergeContext) copyCache ).put( entity, source.instantiate( persister, id ), true ); //before cascade!
}
copyCache
感知到 entity
(即我给定的 Share
对象)不在 copyCache
中,并实例化了一个新的 Share
对象,它显然没有 FileMeta
参考。
我完全糊涂了。
问题的评论中提到了解决方案。为方便起见,在下面给出。
您可以使用 @OneToOne(optional = true)
或简单地使用 @OneToOne
因为 optional
的默认值是 true
.
如果要强制执行 1 对 1 关系,请指定 @OneToOne(optional = false)
。