我有3张桌子:人物 - > Person_Address_Type {person_address_type_id(PK),person_id,address_id,type} - >地址。 Person_Address_Type用于指示Person和地址之间关系的类型。例如:
Mr. A has unique HOME addresses.
Mr. A has one or many OFFICE addresses.
Mr. A has one or many RELAXING addresses.
... And other types of address may be added later.
如何使Hibernate的映射具有以下java实体:
Person {
getHomeAddress(): Address;
getOfficeAddresses(): Address*;
getRelaxingAddresses(): Address*;
}
我知道有短暂的领域。但是,我们不能用瞬态做HQL查询。我需要一个映射。 我该怎么做?
由于
答案 0 :(得分:0)
您的映射应该是这样的
表格结构
CREATE TABLE `person` (
`id_person` BIGINT(20) NOT NULL AUTO_INCREMENT,
`firstname` VARCHAR(50) NULL DEFAULT NULL,
`lastname` VARCHAR(50) NULL DEFAULT NULL,
`birth_date` DATE NULL DEFAULT NULL,
`cell_phone` VARCHAR(15) NULL DEFAULT NULL,
PRIMARY KEY (`id_person`)
)ENGINE=InnoDB;
CREATE TABLE `address_type` (
`id_address_type` BIGINT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id_address_type`)
)ENGINE=InnoDB;
CREATE TABLE `address` (
`id_address` BIGINT(10) NOT NULL AUTO_INCREMENT,
`fk_address_type`BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`id_address`),
CONSTRAINT `FK_ADDRESS_TYPE` FOREIGN KEY (`fk_address_type`) REFERENCES `address_type` (`id_address_type`),
)ENGINE=InnoDB;
CREATE TABLE `person_address` (
`id_person_address` BIGINT(10) NOT NULL AUTO_INCREMENT,
`fk_person` BIGINT(20) NULL DEFAULT NULL,
`fk_address`BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`id_person_address`),
CONSTRAINT `FK_PERSON` FOREIGN KEY (`fk_person`) REFERENCES `person` (`id_person`),
CONSTRAINT `FK_ADDRESS` FOREIGN KEY (`fk_address`) REFERENCES `address` (`id_address`)
)ENGINE=InnoDB;
实体类
<强> Person.java 强>
@Entity
@Table(name = "person",uniqueConstraints = {
@UniqueConstraint(columnNames = "id_person")})
public class Person implements Serializable {
private static final long serialVersionUID = -1798070786993154676L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_person", unique = true, nullable = false)
private Integer id;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="person_address", joinColumns={@JoinColumn(name="fk_person", referencedColumnName="id_person")}
, inverseJoinColumns={@JoinColumn(name="fk_address", referencedColumnName="id_address")})
private Set<Address> address;
// Getter and Setter methods
}
<强> Address.java 强>
@Entity
@Table(name = "address", uniqueConstraints = {
@UniqueConstraint(columnNames = "id_address")})
public class Address implements Serializable {
private static final long serialVersionUID = -6790693372846798580L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_address", unique = true, nullable = false)
private Integer addressId;
@OneToOne(mappedBy="address", cascade=CascadeType.ALL)
private AddressType addressType;
// Getter and Setter methods
}
的 AddressType.java 强> 的
@Entity
@Table(name="address_type",uniqueConstraints = {
@UniqueConstraint(columnNames = "id_address_type")})
public class AddressType {
@Id
@Column(name="id_address_type", unique=true, nullable=false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long addressTypeId;
@OneToOne
@PrimaryKeyJoinColumn
private Address address;
// Getter and Setter methods
}
现在当你拨打getAddress()
时,这将返回与Person相关的所有地址,然后根据地址类型对该地址进行分组,即通过调用address.getAddressType().getName()
方法。
您还可以在Address和AddressType实体之间进行@ManyToMany映射
答案 1 :(得分:0)
从我对Hibernate的简单了解,似乎Hibernate不直接支持关系表的样式。
最简单的方法是创建Person_Address_Type
的单独视图,这样您就可以拥有3个关系表:PERSON_HOME_ADDRESS
,PERSON_OFFICE_ADDRESS
,PERSON_RELAX_ADDRESS
等。
每个视图都包含PERSON_ID
和ADDRESS_ID
使用这些视图,您可以使用ManyToMany/ManyToOne
执行正常的JoinTable
。
但是,如果要直接使用这些实体更新关系,则此方法可能无效(取决于DBMS,某些DBMS允许通过视图更新/插入)。
另一种方法是创建一个新实体,如PersonAddressRelationship
,其中包含对Person,Address和RelationshipType枚举的引用。
然后,Person to Address中的三个关系不会直接映射。相反,您可以根据映射的homeAddress
在relaxAddresses
方法中填充officeAddresses
,@PostLoad
和addressRelationships
的值。 (并在[{1}}方法中更新addressRelationships
基础homeAddress
,relaxAddresses
和officeAddresses
答案 2 :(得分:0)
我刚刚发现@WhereJoinTable是为了这个(理论上,我没有在实践中尝试过)