使用JPA和Hibernate时忽略@Formula注释

4

我有一个定义为Formula的公式:

@Entity
@Table(name = "MyEntity")
@org.hibernate.annotations.Table(appliesTo = "MyEntity")
public class MyEntity
{
    @Enumerated(value = javax.persistence.EnumType.STRING)
    @Transient
    @Formula(value = "select e.state from OTHER_ENTITY e")
    private State state;

    public State getState()
    {
        return this.state;
    }
//setter and another properties
}

但是它正在忽略它。
这是我的“持久化单元”:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myPersistence" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <mapping-file>META-INF/orm.xml</mapping-file>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
        <property name="hibernate.connection.url" value="jdbc:mysql://url:3306/db" />
        <property name="hibernate.connection.username" value="root" />
        <property name="hibernate.connection.password" value="root" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.hbm2ddl.auto" value="validate" />
    </properties>
</persistence-unit>

SQL 语句生成时不包含 Formula

如果我去掉 @TransientJPA 就会尝试加载 state 列,然后失败。

我想根据另一个实体的状态来计算状态。这就是我认为需要使用 Formula 的原因。

谢谢!

Udo。

2个回答

3

我认为这应该可行。我认为@Transient使Hibernate完全忽略了该属性。

@Entity
@Table(name = "MyEntity")
@org.hibernate.annotations.Table(appliesTo = "MyEntity")
public class MyEntity
{
    // MAYBE YOU HAVE TO MOVE IT TO THE GETTER @Enumerated(value = javax.persistence.EnumType.STRING)
    // REMOVE THIS @Transient
    private State state;

    @Enumerated(value = javax.persistence.EnumType.STRING) // MOVED
    @Formula(value = "(select e.state from OtheEntity e)")
    public State getState()
    {
        return this.state;
    }
//setter and another properties
}

1
@Formula 中,或许最好在 select 子句周围加上括号? - WesternGun

3
您试图对状态进行两次映射:一次是通过向字段添加注释,另一次是通过向getter添加注释。请将所有注释放在同一个位置(并且与@Id注释放在同一个位置)。
但这真的很令人困惑。您的状态是瞬态的(意味着它根本没有映射,并且不应从数据库中读取),但它也是枚举的(为什么Hibernate使用此注释,因为它应该是瞬态的),还有一个公式。
最后,公式是添加在用于加载实体的每个SQL中的某些列的公式。因此,它不应包含选择子句或from子句,而只应包含使用表本身的某些列的公式。例如,假设您有一个带有salary列和bonus列的表,您可以为字段totalIncome设置一个公式,该公式为'bonus + salary'。但它不会比那更进一步。

1
不需要Transient。公式已经说明了:这不是数据库中的列,而是从其他值计算出来的值。 - JB Nizet
1
也许我错了,但是在Hibernate文档中的所有公式示例都没有使用Transient注释。通常,只有在尝试加载或持久化表中的内容时,Hibernate才会关心数据库中缺少的列。 - JB Nizet
@ssedano,你是怎么解决的?当使用公式但Hibernate仍在数据库中查找列时,情况的根本原因是什么? - me1111
我采用了完全不同的方法,因为根据答案所述,我的状态没有被保留。虽然我记不清确切的解决方案了。 - ssedano
我进行了测试,并发现在持久化时,带有@Formula但没有@Transient的字段不会引起问题。实体已成功持久化。 - WesternGun
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接