我正在创建一个系统,其中有一些实体具有一些常见的属性,如地址(带有街道,数字,拉链等)和电话(数字,类型等),我不想要在每个实体上重复这些列。
这是一个例子:
我在使用多态关联开发Ruby On Rails时使用了类似的东西。我在Java / JPA / Hibernate上搜索过类似的东西,找不到类似的东西。我发现了许多关于JPA继承的事情,但我不太了解它。
您能举例说明如何建模以及如何使用它吗?
修改
在阅读我的问题后,我认为还不够清楚,所以让我在这里添加我的数据库架构:
Student
-------
id bigint
name varchar
birth_date date
...
Teacher
-------
id bigint
name varchar
birth_date date
department varchar
...
StaffMember
-------
id bigint
name varchar
birth_date date
department varchar
function varchar
...
Address
-------
id bigint
street varchar
number int
...
entity_id bigint
entity_type varchar
Phone
-----
id bigint
type varchar
number varchar
...
entity_id bigint
entity_type varchar
对于Address
和Phone
,entity_id
和entity_type
列都是对Student
,Teacher
和StaffMember
的引用
但是如何使用Hibernate / JPA映射它?
答案 0 :(得分:1)
如果您不介意使用特定于Hibernate的注释,可以使用@Any和@AnyDef注释来执行您想要的操作。您需要为与Address相关的每个实体类型指定一个@MetaValue条目,以便Hibernate知道如何为item_type存储正确的值
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import org.hibernate.annotations.Any;
import org.hibernate.annotations.AnyMetaDef;
import org.hibernate.annotations.MetaValue;
@Entity
public class Address {
@Any(metaColumn = @Column(name = "ITEM_TYPE"))
@AnyMetaDef(idType = "long", metaType = "string",
metaValues = {
@MetaValue(targetEntity = Student.class, value = "STUDENT"),
@MetaValue(targetEntity = Teacher.class, value = "TEACHER")
})
@JoinColumn(name="ITEM_ID")
private Object item;
@Id
@GeneratedValue
private Long id;
@Column
private String type;
@Column
private String street;
@Column
private int number;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Object getItem() {
return item;
}
public void setItem(Object item) {
this.item = item;
}
@Override
public String toString() {
return "Address{" +
"person=" + item +
", id=" + id +
", type='" + type + '\'' +
", street='" + street + '\'' +
", number=" + number +
'}';
}
}
现在,您可以在任何具有正确@MetaValue条目的bean中使用Address,这两个条目都是@ManyToOne关联:
@ManyToOne
protected Address address;
或@OneToMany协会:
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
protected Collection<Address> addresses;
我使用Spring Boot创建了一个简单的测试项目,它看起来效果很好!
答案 1 :(得分:0)
我认为您需要的是使用通用存储库类。
这篇文章http://blog.netgloo.com/2014/12/18/handling-entities-inheritance-with-spring-data-jpa解释了它。让我知道是否适合你。
答案 2 :(得分:0)
这些方面的东西:
@Embeddable
public class Address {
// Fields & accessors
// Do the Phone class in similar fashion
}
@Entity
@DiscriminatorColumn(name = "entity_type")
public abstract class Person {
@Id
private Integer id;
private String name;
@Embedded
private Address homeAddress;
@Embedded
private Phone homePhone;
// Other shared fields & accessors
}
@Entity
public abstract class Employee extends Person {
@Embedded
private Phone mobilePhone;
@Embedded
private Phone officePhone;
//...
}
@Entity
public class Students extends Person {
}
@Entity
public class StaffMember extends Employeee {
}
@Entity
public class Teacher extends Employeee {
@Embedded
private Address officeAddress;
// Accessors & other ...
}