休眠一对一或一个或两个映射.例外:尝试从空的一对一属性分配ID? [英] Hibernate one to zero or one mapping. Exception: attempted to assign id from null one-to-one property?

查看:72
本文介绍了休眠一对一或一个或两个映射.例外:尝试从空的一对一属性分配ID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我像@Tony那样在休眠的情况下进行一对一或零映射或.

我有一个课程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引用. /p>

我完全困惑了.

解决方案

该问题的注释中提到了解决方案.为方便起见,在下面给出.

由于optional的默认值为true,因此您可以使用@OneToOne(optional = true)或仅使用@OneToOne.

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

I do as @Tony answered in Hibernate one to zero or one mapping.

I have a 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...
}

And a class 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...
}

And when I tried to fill my FileMeta with Share:

    Share share = new Share();
    share.setFileMeta(fileMeta);
    fileMeta.setShare(share);
    fileMetaRepository.save(fileMeta);

I received exception: attempted to assign id from null one-to-one property

I followed into Hibernate. And noticed that, in generator method, the associatedObject is not my given Share object at all, but a new Share object instantiated by a EventSource

In 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!
    }

The copyCache sensed that entity (i.e my given Share object) is not in copyCache, and instantiated a new Share object, which doesn't have a FileMeta reference obviously.

I've completely confused.

解决方案

The solution was mentioned in the comments to the question. It's given below for convenience.

You can use @OneToOne(optional = true) or simply @OneToOne since default value of optional is true.

If you want to enforce 1 to 1 relationship, specify @OneToOne(optional = false).

这篇关于休眠一对一或一个或两个映射.例外:尝试从空的一对一属性分配ID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆