复杂连接的 Hibernate 映射

标签 hibernate inner-join hibernate-mapping

我有试图映射到新代码的遗留代码。

OLD_PERSON
pid
sid
name
age

NEW_PERSON
pid
sid
fid
age

RESOLVE_PERSON
pid
fid
status

Java类
domain.Person {
 ID _id;
 String _name;
 Integer _age;
}

在遗留世界中,只有一张表:OLD_TABLE。 hibernate 映射很简单,只有一个类和它的列。在新世界中,我必须使用以上 3 个表并生成一个名称来自 的实体。 OLD_PERSON 和年龄从 NEW_PERSON .所以基本上一个 SQL 查询是:
select op.name as name, np.age as age
from OLD_PERSON op
INNER JOIN RESOLVE_PERSON rp
on rp.pid = op.pid
INNER JOIN NEW_PERSON np 
on np.pid = rp.pid and np.fid = rp.fid and np.sid = op.sid
where rp.status = 'CURRENT'

经过研究/谷歌搜索,我发现我可以在 hibernate xml 中使用相当于“JOIN table”的“Secondary tables”。 注意:我不能使用注释,因为这段代码很旧,我仍然在 hibernate3.5.6 上。

所以我在我的映射文件中添加了一个连接表:
<class name="domain.Person" table="OLD_PERSON">
        <composite-id name="_id" class="Id">
            <key-property access="property" name="key1" type="long" column="pid" />
            <key-property access="property" name="key2" type="int" column="sid" />

            <generator class="assigned" />
        </composite-id>

        <property name="_Name" type="String" column="name" />

        <join table="NEW_PERSON" fetch="join" inverse="false">
          <key>
            <column name="pid" />
            <column name="sid" />
          </key>
            <property name="_age" column="age" not-null="true" />
        </join>
</class>

但是加入到 NEW_PERSON 表需要与 的内部联接RESOLVE_PERSON table 。我尝试使用 子选择 但它不是正确的使用方法。我无法插入 公式这里的任何地方。

关于如何实现这一点的任何指示?我本质上要求的是如何对 JOIN 应用标准/约束检查。

最佳答案

我和你的问题有类似的情况。我已将第三个表映射到一个实体,并使用该实体的 DAO 通过其属性获取某些内容。

这是代码(因为我使用了注解,所以这不是你可以直接使用的,但希望它能给你一些启发),

@Entity
@Table(name = "resolve_person")
public class ResolvePerson implements java.io.Serializable {
    private OldPerson old;
    private NewPerson new;

    ...

    @ManyToOne // you may change it to other relationships
    @JoinColumn(name = "pid", nullable = false)
    public OldPerson getOldPerson () {
        return this.old;
    }

    public void setOldPerson (OldPerson old) {
        this.old = old;
    }

    @Id
    @GeneratedValue(generator = "idGenerator")
    @GenericGenerator(name = "idGenerator", strategy = "foreign",
            parameters = { @org.hibernate.annotations.Parameter(name = "property", value = "fid") })
    @Column(name = "fid", nullable = false, unique = true)
    public NewPerson getNewPerson () {
        return this.New;
    }

    public void setNewPerson (NewPerson new) {
        this.new = new;
    }
}

DAO很正常,
public List findByProperty(String propertyName, Object value) {
        log.debug("finding ResolvePerson instance with property: "
                + propertyName + ", value: " + value);
        try {
            String queryString = "from ResolvePerson as model where model."
                    + propertyName + "= ?";
            Query queryObject = getSession().createQuery(queryString);
            queryObject.setParameter(0, value);
            return queryObject.list();
        } catch (RuntimeException re) {
            log.error("find by property name failed", re);
            throw re;
        }
    }

现在,您可以将“状态”属性设置为“当前”进行查询。

关于复杂连接的 Hibernate 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42893317/

相关文章:

java - 在 JPA 持久性单元中定义一个名为的重复生成器是否可以?

java - Hibernate:合并parentEntity时childEntity null id

java - Hibernate中如何实现触发器?

java - 过滤延迟初始化集合

java - 从多对多关系返回值

java - Hibernate 中的复合 id

sql - 具有WHERE子句的内部联接影响第二个联接

sql - 如何让 SQL INNER JOIN 接受空结果

mysql - 不允许 Django 内连接

java - 连接数据库的 Hibernate 问题 - java.lang.NoClassDefFoundError : net/bytebuddy/NamingStrategy$SuffixingRandom$BaseNameResolver