1

我正在使用 Hibernate 4.3.6.Final 和 WildFly 16。@OneToOne 关系有两个问题。

1.) 第一个问题:Unknown mappedBy in: at.home.digest.model.Expose.home, 引用属性unknown: at.home.digest.model.Home.expose"}}

这些是我的实体:

@Entity
@Table(name = "home",
    uniqueConstraints =  @UniqueConstraint (columnNames = {"URL"})
)
@Access(AccessType.FIELD)
public class Home implements Serializable { 

    @OneToOne (fetch = FetchType.LAZY, mappedBy = "home", cascade = CascadeType.ALL)
    @JoinColumn(name = "expose_id")
    private Expose expose;

    public Expose getExpose() {
        return expose;
    }

    public void setExpose(Expose expose) {
        this.expose = expose;
    }
    ................

}

公开实体:

@Entity
@Table(name ="expose")
@Access(AccessType.FIELD)
public class Expose  implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", updatable=false, nullable=false)
    private int id; 

    @OneToOne (fetch = FetchType.EAGER, mappedBy = "expose", cascade=CascadeType.PERSIST )
    @JoinColumn(name = "home_id")
    private Home home;

    @ManyToOne ( optional = false, cascade=CascadeType.MERGE )
    @JoinColumn(name = "contact_id")
    private Contact contact;

}

部署应用程序后,我收到:

Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: at.home.digest.model.Expose.home, referenced property unknown: at.home.digest.model.Home.expose"}}

2.) 第二个问题:首先,我通过从 Expose 实体中删除属性 mappedBy = "expose" 来克服第一个问题,即 Expose 实体现在看起来像:

@Entity
@Table(name ="expose")
@Access(AccessType.FIELD)
public class Expose  implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", updatable=false, nullable=false)
    private int id; 


    @OneToOne (fetch = FetchType.EAGER, cascade=CascadeType.PERSIST )
    @JoinColumn(name = "home_id")
    private Home home;

    @ManyToOne ( optional = false, cascade=CascadeType.MERGE )
    @JoinColumn(name = "contact_id")
    private Contact contact;

    }

现在我不再面临第一个问题了。但是,当保存主实体时,它不再引用相应的公开实体。相反,SQL 表 home 中的字段 expose_id 为空。:

这是我保存实体的源代码:

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void saveEntity(Home home) throws EntityExistsException {

    Expose expose = null;
    if (home.getExpose() != null && home.getExpose().getContact() != null) {
        Contact contact = this.em.merge(home.getExpose().getContact());
        home.getExpose().setContact(contact);
        expose = this.em.merge(home.getExpose());
        home.setExpose(expose);
    }
    this.em.persist(home);
    if (expose != null) {
        expose.setHome(home);
        expose = this.em.merge(expose);
        home.setExpose(expose);
        this.em.merge(home);
    }
}

具有对应暴露实体的主实体被保存而不引用对应的暴露实体,即主表中的expose_id列为空。但是,相应的暴露实体与对主实体的引用一起保存,即暴露表中的列 home_id 正确地引用了主表中的相应行。

4

1 回答 1

0

我无法完全解释错误在哪里。但是,我解决了以下问题:

1.) 我将 MySQL 数据库保存在一个文件中(使用 mysqldump),然后删除了整个数据库。

2.)当我使用 MySQL Server 5.7 时,我需要将我的 persistence.xml 中的 Hibernate Dialect 更改为

org.hibernate.dialect.MySQL57Dialect 

(早些时候是org.hibernate.dialect.MySQLDialect)。我还将属性设置hibernate.hbm2ddl.autocreate,以便休眠在下次部署应用程序时重新创建我的所有表

3.)我在此处的文章之后更改了 Home 和 Expose 之间的休眠 @OneToOne 映射:

https://hellokoding.com/jpa-one-to-one-shared-primary-key-relationship-mapping-example-with-spring-boot-maven-and-mysql/

通过这种方式,Expose 和 Home 现在共享一个相同的主键,这对提高效率很重要。我的 Home 和 Expose 实体现在如下:

@Entity
@Table(name = "home",
    uniqueConstraints =  @UniqueConstraint (columnNames = {"URL"})
)
@Access(AccessType.FIELD)
public class Home implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id; 


    @OneToOne (fetch = FetchType.LAZY,  mappedBy = "home", cascade = CascadeType.ALL)
    private Expose expose;

    // ..... setters and getters here

}

@Entity
@Table(name ="expose")
@Access(AccessType.FIELD)
public class Expose  implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private int id; 

    @OneToOne (fetch = FetchType.LAZY)
    @JoinColumn (name = "id")
    @MapsId
    private Home home;

        // ..... setters and getters here

}

4.) 保存主实体的代码现在如下所示:

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void updateEntityWithExpose(Home home) throws EntityExistsException {
        Expose expose = null;
        if (home.getExpose() != null && home.getExpose().getContact() != null) {
            Contact contact = this.em.merge(home.getExpose().getContact());
            home.getExpose().setContact(contact);
        }
        this.em.persist(home);
    }
于 2019-09-08T05:56:07.680 回答