@OneToOne关系中的两个问题



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

1.( 第一个问题:未知映射:at.home.digest.model.Expose.home,引用属性未知: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 表主页中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);
}
}

具有相应公开实体的 Home 实体被保存时不引用相应的公开实体,即主表中的expose_id列为 null。但是,相应的公开实体与对主实体的引用一起保存,即公开表中的列home_id正确引用了主表中的相应行。

我不能完全解释错误在哪里。但是,我按如下方式解决了问题:

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

2.(当我使用MySQL Server 5.7时,我需要将Hibernate方言更改为我的持久性.xml

org.hibernate.dialect.MySQL57Dialect 

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

3.( 我按照此处的文章更改了主页和公开之间的休眠@OneToOne映射:

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

通过这种方式,Expose 和 Home 现在共享同一个主键,这有助于提高效率。"我的主页"和"公开"实体现在如下所示:

@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);
}

相关内容

  • 没有找到相关文章

最新更新