在我们的项目中,我们有一个实体'餐厅'有近30个领域(有些与其他实体有关系)。所以,每次我们需要一家餐厅'即使对于少数字段,也会检索所有其他字段。这会影响性能。因此,在HBM文件中,我们编写了两个指向同一物理类和相同数据库表的类,如下所示。
=== restaurant.hbm.xml ===
<!-- Light Weight Version -->
<class name="com.raj.model.Restaurant" table="RESTAURANTS" entity-name="RestaurantLite"
dynamic-update="false" dynamic-insert="false">
<cache usage="read-only"/>
<!-- few basic properties and relationships -->
</class>
<!-- Restaurant -->
<class name="com.raj.model.Restaurant" table="RESTAURANTS" entity-name="Restaurant">
<!-- all properties and relationships -->
</class>
在其中一个DAO实施中,我们使用的是Criteria,其中包括&#39; RestaurantLite&#39;并返回餐馆名单,如下所示。
Criteria criteria = session.createCriteria("RestaurantLite");
// criteria related stuff
return new LinkedHashSet<Restaurant>(criteria.list());
现在我们要删除所有hbm文件并使用注释。那么如何使用针对entites的注释来完成同样的事情呢?我们需要创建一个额外的课程&#39; RestaurantLite&#39;?如果那时,上述标准如何回归&#39;餐厅&#39;对象??
答案 0 :(得分:44)
本主题以及如何将其用于延迟抓取属性,详细介绍了in this article。
总结一下,以下映射将演示如何将多个实体映射到同一个数据库表:
@Entity(name = "Post")
public class Post {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
@Entity(name = "PostSummary")
@Table(name = "Post")
@Immutable
public class PostSummary {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Entity(name = "UpdatablePostSummary")
@Table(name = "Post")
@DynamicUpdate
public class UpdatablePostSummary {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Hibernate可以正常工作:
@Test
public void testOneTableMultipleEntities() {
doInTransaction(session -> {
Post post = (Post) session.get(Post.class, 1L);
PostSummary postSummary = (PostSummary) session.get(PostSummary.class, 1L);
UpdatablePostSummary updatablePostSummary = (UpdatablePostSummary) session.get(UpdatablePostSummary.class, 1L);
assertEquals(post.getName(), postSummary.getName());
assertEquals(post.getName(), updatablePostSummary.getName());
updatablePostSummary.setName("Hibernate Master Class Tutorial.");
});
}
PostSummary
只是对原始实体的只读视图,因此我使用@Immutable
对其进行了注释。
UpdatablePostSummary
标有@DynamicUpdate
,因此您也可以从此View实体传播更改。
此测试也可在GitHub上找到。
答案 1 :(得分:0)
我有一个类似的问题。我有两个类,基类 DocumentContent 和派生类 DocumentContentWithData :
DocumentContent {
private Long documentContentId;
private InputStream contentStream;
private File importFile;
... and several other attributes
}
DocumentContentWithData extends DocumentContent {}
我为这两个类定义了一个休眠映射,为 DocumentContent 类定义了一个没有 contentStream 的映射,为 DocumentContentWithData 类定义了一个映射与 contentStream 。
使用方法 Session.get(Class,ID)保存类 DocumentContentWithData 的数据,并且获取两个类的实例也可以。
但是下面的代码中的查询返回两个实体,一个作为 DocumentContent 的实例,另一个作为 DocumentContentWithData 的实例,尽管 importFile 在数据库中:
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<DocumentContent> criteriaQuery = criteriaBuilder.createQuery(DocumentContent.class);
Root<DocumentContent> root = criteriaQuery.from(DocumentContent.class);
criteriaQuery.select(root).where(criteriaBuilder.equal(root.get("importFile"), importFile));
Query<DocumentContent> query = session.createQuery(criteriaQuery);
List<DocumentContent> contentList = query.getResultList();
有人可以解释这种行为。当我不从 DocumentContent 派生类 DocumentContentWithData 并复制所有属性时,它将起作用。但是,这不是一个很好的解决方案。
答案 2 :(得分:-1)
您必须在类上添加注释@ Entity,@ Table(name =“RESTAURANT”),添加注释并在hbm文件中替换您的详细映射
这是一个完整的示例:http://viralpatel.net/blogs/hibernate-many-to-many-annotation-mapping-tutorial/