首先,我读过Hibernate - One table with multiple entity? .
但是,我想将两个实体映射到同一个表,但我希望它们都是实体,我可以从中进行选择。我的意思是:
所以它是实体之间的 1:1 关系,但在 DB 中仍然是 1 个表。
如果我使用上述链接中建议的解决方案(组件关键字)来执行此操作,则无法直接查询地址(我可以通过 Person 实体访问它)。我希望能够做到
session.createCriteria(Adres.class)
Run Code Online (Sandbox Code Playgroud)
我怎么做?
更新:我在地址映射中尝试了实体之间的一对一关联:
<one-to-one name="Person " class="model_mapowanie_xml.Person "/>
Run Code Online (Sandbox Code Playgroud)
和个人映射:
<one-to-one name="Address" class="model_mapowanie_xml.Address "/>
Run Code Online (Sandbox Code Playgroud)
两个类都有引用另一个类的字段。选择记录可以很好地解决这个问题。但是,如何在一个交易中使用两个实体添加一条记录?(Id 是数据库生成的)
Address ad = new Address();
ad.setProperty("Sydney");
Person p = new Person();
p.setProperty("John");
p.setAddress(ad);
session.save(p);
Run Code Online (Sandbox Code Playgroud)
并且只保存了 Person 部分,address 属性保持为空。
您应该能够使用@Table注释来完成此操作。这些实体将被视为不同的实体,但将映射到同一个表上。
@Entity
@Table(name="PERSON_TABLE")
class Person {}
@Entity
@Table(name"PERSON_TABLE")
class Address {}
Run Code Online (Sandbox Code Playgroud)
编辑:
如果您想将两个实体保存在一个事务中,您必须使用显式保存它们Session或将cascade属性设置为关系上的级联操作。我猜想当您对 Person 执行某些操作时,您希望对 Address 进行级联操作。如果您使用注释,请参阅CascadeType 。
在你的 hbm 中它看起来像
<one-to-one name="Person" class="model_mapowanie_xml.Person" cascade="all"/>
使用 JPA 和 Hibernate 实现这一点非常简单。
假设您正在使用以下book数据库表:
现在,您可以将两个实体:Book和映射BookSummary到此表。
首先,我们将创建一个BaseBook由所有实体扩展的抽象类:
@MappedSuperclass
public abstract class BaseBook<T extends BaseBook> {
@Id
@GeneratedValue
private Long id;
@NaturalId
@Column(length = 15)
private String isbn;
@Column(length = 50)
private String title;
@Column(length = 50)
private String author;
public Long getId() {
return id;
}
public T setId(Long id) {
this.id = id;
return (T) this;
}
public String getIsbn() {
return isbn;
}
public T setIsbn(String isbn) {
this.isbn = isbn;
return (T) this;
}
public String getTitle() {
return title;
}
public T setTitle(String title) {
this.title = title;
return (T) this;
}
public String getAuthor() {
return author;
}
public T setAuthor(String author) {
this.author = author;
return (T) this;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,BookSummary实体只是扩展了BaseBook超类并且不添加额外的实体属性。
@Entity(name = "BookSummary")
@Table(name = "book")
public class BookSummary extends BaseBook<BookSummary> {
}
Run Code Online (Sandbox Code Playgroud)
另一方面,Book实体扩展BaseBook超类并映射properties属性。
@Entity(name = "Book")
@Table(name = "book")
@TypeDef(
name = "jsonb",
typeClass = JsonBinaryType.class
)
@DynamicUpdate
public class Book extends BaseBook<Book> {
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb")
private String properties;
public String getProperties() {
return properties;
}
public Book setProperties(String properties) {
this.properties = properties;
return this;
}
public ObjectNode getJsonProperties() {
return (ObjectNode) JacksonUtil
.toJsonNode(properties);
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您可以保留一个Book实体:
entityManager.persist(
new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea")
.setProperties(
"{" +
" \"publisher\": \"Amazon\"," +
" \"price\": 44.99," +
" \"publication_date\": \"2016-20-12\"," +
" \"dimensions\": \"8.5 x 1.1 x 11 inches\"," +
" \"weight\": \"2.5 pounds\"," +
" \"average_review\": \"4.7 out of 5 stars\"," +
" \"url\": \"https://amzn.com/973022823X\"" +
"}"
)
);
Run Code Online (Sandbox Code Playgroud)
或BookSummary:
entityManager.persist(
new BookSummary()
.setIsbn("978-1934356555")
.setTitle("SQL Antipatterns")
.setAuthor("Bill Karwin")
);
Run Code Online (Sandbox Code Playgroud)
您可以获取BookSummary实体:
BookSummary bookSummary = entityManager
.unwrap(Session.class)
.bySimpleNaturalId(BookSummary.class)
.load("978-9730228236");
assertEquals(
"High-Performance Java Persistence",
bookSummary.getTitle()
);
Run Code Online (Sandbox Code Playgroud)
或Book实体,如果你想:
Book book = entityManager
.unwrap(Session.class)
.bySimpleNaturalId(Book.class)
.load("978-9730228236");
assertEquals(
"High-Performance Java Persistence, 2nd edition",
book.getTitle()
);
Run Code Online (Sandbox Code Playgroud)
因此,将多个实体映射到同一个数据库表,不仅可以让我们更有效地获取数据,而且还可以加快脏检查过程,因为 Hibernate 必须检查更少的实体属性。
使用这种方法的唯一缺点是,您必须确保不会为同一个数据库表记录获取多个实体类型,否则,这会在刷新持久性上下文时导致不一致。
| 归档时间: |
|
| 查看次数: |
18101 次 |
| 最近记录: |