Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use entity field in Hibernate @Formula

Many times I'm using @Formula in my entities. But always it was a simple query or stored procedure with parameter which I can take as filed from table. Now I need to user some property from related object. But I see exception when try to get object from DB. Please see an example below

@Entity
@Table(name = "MINISTRY")
public class Ministry {

    @Id
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    // unnecessary code

}

@Entity
@Table(name = "DEPARTMENT")
public class Department {

    @Id
    @Column(name = "ID")
    private Long id;

    @Column(name = "DEP_NAME")
    private String departmentName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "MINISTRY_ID")
    private Ministry ministry;

    // unnecessary code
}

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @Column(name = "ID")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "DEPARTMENT_ID")
    private Department department;

    @Formula("test_package.calc_something(department.ministry.id)")
    private BigDecimal someMetric;

    // unnecessary code

}

How I should use entity prop in @Formula. I don't want to write something like

select d.ministry.id from Department d ...
like image 773
Dmytro Avatar asked Aug 25 '15 14:08

Dmytro


People also ask

How do I use @formula in hibernate?

You can use the @Formula annotation to provide an SQL snippet which Hibernate will execute when it fetches the entity from the database. The return value of the SQL snippet gets mapped to a read-only entity attribute. I use the annotation in the following example to calculate the age of an author. …

How does @entity work with @Hibernate?

Hibernate will scan that package for any Java objects annotated with the @Entity annotation. If it finds any, then it will begin the process of looking through that particular Java object to recreate it as a table in your database!

What is @formula annotation in hibernate annotation?

Hibernate Annotation has some property annotation that provides different type of job. If we want to apply a virtual property in your entity to get a calculated value, we can use @Formula annotation to set the formula.

What is @filterdef annotation in hibernate?

The @FilterDef annotation defines the filter name and a set of its parameters that will participate in the query. The type of the parameter is the name of one of the Hibernate types ( Type, UserType or CompositeUserType ), in our case, an int. The @FilterDef annotation may be placed either on the type or on package level.


1 Answers

If you read the JavaDoc of Formula you will see:

The formula has to be a valid SQL fragment

So you will have to use SQL like:

 @Formula("test_package.calc_something("
            + "select DEP.MINISTRY_ID from DEPARTMENT DEP where DEP.ID = DEPARTMENT_ID"
         + ")")
 private BigDecimal someMetric;

The only thing that is modified by Hibernate in the fragment before writing it to SQL: It will add the table alias to your columns (as you can't predict that). I mention that, as only a rudimentary SQL parser is used for that, which will insert the alias at wrong positions for more complex fragments.

A remark about performance: The formula is executed for every Department entity that you load, even if you only want to use the attribute for sorting or filtering (just guessing from the name of the attribute) - unless you use @Basic(fetch = FetchType.LAZY) and turn bytecode instrumentation on (or emulate that with FieldHandled).

like image 160
Tobias Liefke Avatar answered Oct 31 '22 02:10

Tobias Liefke