与连接表中的类型的单向关联

时间:2013-12-09 05:28:19

标签: java hibernate mapping entity-relationship

我有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查询。我需要一个映射。 我该怎么做?

由于

3 个答案:

答案 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_ADDRESSPERSON_OFFICE_ADDRESSPERSON_RELAX_ADDRESS等。

每个视图都包含PERSON_IDADDRESS_ID

使用这些视图,您可以使用ManyToMany/ManyToOne执行正常的JoinTable

但是,如果要直接使用这些实体更新关系,则此方法可能无效(取决于DBMS,某些DBMS允许通过视图更新/插入)。

另一种方法是创建一个新实体,如PersonAddressRelationship,其中包含对Person,Address和RelationshipType枚举的引用。

然后,Person to Address中的三个关系不会直接映射。相反,您可以根据映射的homeAddressrelaxAddresses方法中填充officeAddresses@PostLoadaddressRelationships的值。 (并在[{1}}方法中更新addressRelationships基础homeAddressrelaxAddressesofficeAddresses

答案 2 :(得分:0)

我刚刚发现@WhereJoinTable是为了这个(理论上,我没有在实践中尝试过)