HIbernate 4:将最后一个审计行映射为关联属性

时间:2012-10-23 07:58:14

标签: hibernate subquery jointable

我需要映射两个类Person和PersonAudit:

public class Person implements Serializable {

    private int id;
    private String name;
    private PersonAudit personAudit;

    public Person() {
    }

    //getters and setters omitted
}

public class PersonAudit implements Serializable {

    private int id;
    private Person person;
    private String name;
    private String user;
    private Date date;

    public PersonAudit() {
    }

    //getters and setters omitted
}

表PersonAudit将历史更改存储在Person表中。

是否可以映射 Person.personAudit 属性以始终获取最后一个审核寄存器,因为Person表实际上没有任何列引用PersonAudit表?

我正在关注Employee-Employment-Organization文档的示例(http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#assoc-complex),但它似乎仅在Employee表包含orgId列时才有效。

这是到目前为止Person类的映射:

<class catalog="test" name="test.Person" table="Person">
    <id name="id" type="int">
      <column name="Id"/>
      <generator class="increment"/>
    </id>
    <property name="name" type="string">
      <column length="30" name="Name" not-null="true"/>
    </property>

    <join table="PersonAudit"> 
        <subselect>
            select Id,IdPerson
            from PersonAudit
            group by IdPerson
            having Id = max(Id)
        </subselect>
        <key column="Id" />
        <many-to-one name="personAudit" class="test.PersonAudit" column="???"/>
    </join>
</class>

因此,多对一不是可行的方法,我该如何解决这种情况?

任何帮助我都会感激,提前谢谢。

2 个答案:

答案 0 :(得分:1)

公式参考适用于此方案。在我的头顶,它应该看起来像:

<many-to-one name="personAudit"
  formula="(SELECT Max(pa.Id) FROM PersonAudit pa WHERE pa.IdPerson = Id)" > 
</many-to-one>

答案 1 :(得分:1)

对于那些可能需要将此类关联映射为组件的人,这是解决此问题的另一种方法:

<join table="PersonAudit" optional="true"> 
        <subselect>
            select pa.Id,pa.IdPerson,pa.Name,pa.User,pa.Date
            from PersonAudit pa
            where pa.Id = 
                ( select max(Id)
                    from PersonAudit
                    where IdPerson = Id)
        </subselect>    
        <key column="IdPerson" />
        <component name="personAudit" class="test.PersonAudit">
            <property name="id" column="Id"/>
            <property name="name" column="Name"/>
            <property name="user" column="USer"/>
            <property name="date" column="Date"/>
        </component>
</join>