java 使用 JPA 休眠,忽略 @Formula

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7824805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:34:58  来源:igfitidea点击:

Hibernate with JPA ignoring @Formula

javahibernatejakarta-eejpapersistence

提问by ssedano

I have a Formuladefined as:

我有一个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
}

But it is ignoring it.

但它忽略了它。

Here is my Persistence Unit:

这是我的Persistence Unit

<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>

The sql are generated without the Formula.

生成的 sql 没有Formula.

If I remove the @Transientthe JPAtries to load the statecolumn and then fails.

如果我删除@TransientJPA尝试加载state列,然后失败。

I want to calculate the state based on the state of another entity. That's why the I think a Formulaworks.

我想根据另一个实体的状态计算状态。这就是为什么我认为 aFormula有效。

Thank you!

谢谢!

Udo.

你做。

采纳答案by JB Nizet

You're trying to map the state twice : once by adding annotations to the field, and once by adding annotations to the getter. Put all the annotations at the same place (and at the same place as the @Idannotation).

您尝试两次映射状态:一次通过向字段添加注释,一次向 getter 添加注释。将所有注释放在同一个地方(和注释放在同一个地方@Id)。

But this is really confusing. Your state is transient (meaning it's not mapped at all, and should not be read from the database), but it's also enumerated (why would Hibernate use this annotation since it's supposed to be transient), and a formula.

但这真的很令人困惑。你的状态是瞬态的(意味着它根本没有映射,不应该从数据库中读取),但它也是枚举的(为什么 Hibernate 会使用这个注释,因为它应该是瞬态的)和一个公式。

Finally, a formula is some piece of SQL that's added in every SQL that is used to load your entity. So it should not contain a select clause, or a from clause, but just a formula using some of the columns of the table itself. For example, suppose you have a table with a column salaryand a column bonus, you could have a formula for a field totalIncomewhich would be 'bonus + salary'. But id doesn't go much further than that.

最后,公式是添加到用于加载实体的每个 SQL 中的一段 SQL。因此,它不应包含 select 子句或 from 子句,而应仅包含使用表本身某些列的公式。例如,假设您有一个包含一列salary和一列的表bonus,您可以有一个字段的公式,totalIncome即“奖金 + 工资”。但 id 并没有比这更进一步。

回答by aalku

I think this should work. I think @Transient is making Hibernate ignore the attribute at all.

我认为这应该有效。我认为@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
}