【问题标题】:Hibernate one to zero or one mapping. Exception: attempted to assign id from null one-to-one property?休眠一对零或一映射。例外:试图从空的一对一属性分配 id?
【发布时间】:2017-10-22 20:13:39
【问题描述】:

我按照@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...
}

当我尝试用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 对象

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 引用。

我完全糊涂了。

【问题讨论】:

  • 你想在这里做什么“当我试图用 Share 填充我的 FileMeta 时”?看起来模棱两可。
  • 我的意思是fileMeta.setShare(share);。我的意思是在share 表中插入一行后,在file_meta 表中填写一行FK_SHARE
  • FileMeta <-> Share 关系的双方如何成为一体?如果正向映射是多对一,则反向映射一定是一对多
  • @crizzis 。请参阅此链接link。看起来很多人已经设法通过这个正向映射实现one to zero or one many-to-one 而反向映射是one-to-one 方法。
  • 我明白这一点。正如我所说,one-to-one 默认为optional,这意味着nullFileMeta.shareFileMeta.garbage 的有效值。您能解释一下为什么简单的one-to-one 在您的情况下不起作用吗?

标签: java hibernate jpa spring-data-jpa persistence


【解决方案1】:

问题的 cmets 中提到了解决方案。为方便起见,在下面给出。

您可以使用@OneToOne(optional = true) 或简单地使用@OneToOne,因为optional 的默认值是true

如果要强制执行一对一关系,请指定@OneToOne(optional = false)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    相关资源
    最近更新 更多