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)