我这样做@Tony在Hibernate one to zero or one mapping回答。
我有一个班级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...
}
班级Share
。
@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...
}
当我尝试用FileMeta
填充Share
时:
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
对象,而是由Share
实例化的新EventSource
对象
在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
对象,其中没有&# 39;显然有FileMeta
引用。
我完全糊涂了。
答案 0 :(得分:0)
该问题的评论中提到了解决方案。为方便起见,下面给出了它。
您可以使用@OneToOne(optional = true)
或@OneToOne
,因为optional
的默认值为true
。
如果要强制执行1对1关系,请指定@OneToOne(optional = false)
。