Ankit Katiyar
Ankit Katiyar

Reputation: 3001

@Formula not working in hibernate with object

I have a enum of few status value

NEW, REVIEWD, PUBLISHED, PENDING, UPDATED, SPAM, DUPLICATE, IRRELEVANT, UNPUBLISHED

I don't want to use them as enumerated so created one entity for that. For convenient I want to keep a column in entity to initialize status from enum and convert that enumerated value to a Object of status entity. for this..

I have two entity. I want to refer a column with value from another entity.

Basically I want to initialize a object with formula.

Entities are

@Entity
@Table(name = "event_status")
public class EventStatus {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="eventStatusId")
    private Integer eventStatusId;

    @Enumerated(EnumType.STRING)
    @Column(unique = true,name="eventStatusType")
    private EventStatusType eventStatusType;

    public EventStatus() {
        this(EventStatusType.NEW);
    }

    public EventStatus(EventStatusType eventStatusType) {
        super();
        this.eventStatusType = eventStatusType;
    }

    public Integer getEventStatusId() {
        return eventStatusId;
    }

    public EventStatusType getEventStatusType() {
        return eventStatusType;
    }

    public void setEventStatusId(Integer eventStatusId) {
        this.eventStatusId = eventStatusId;
    }

    public void setEventStatusType(EventStatusType eventStatusType) {
        this.eventStatusType = eventStatusType;
    }
}

I have another entity in which I am referring object of this entity

@Entity
@Table(name = "event_")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Event implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id_")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Transient
    public EventStatusType eventStatusType = EventStatusType.NEW;

    @ManyToOne(fetch = FetchType.EAGER, targetEntity = EventStatus.class)
    @Formula("select * from event_status where eventStatusId= 1")
    private EventStatus status;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public EventStatus getStatus() {
        System.out.println("Event.getStatus() " + status);
        return status;
    }

    public void setStatus(EventStatus status) {
        System.out.println("Event.setStatus()");
        this.status = status;
    }
}

This is not giving any exception but not initializing this value. Is it possible to initialize this EntityStatus with value of eventStatusType in Event entity

Upvotes: 4

Views: 12178

Answers (1)

Radim Köhler
Radim Köhler

Reputation: 123901

I would like to explain that based on the documentation:

5.1.4.1.5. Formula

Sometimes, you want the Database to do some computation for you rather than in the JVM, you might also create some kind of virtual column. You can use a SQL fragment (aka formula) instead of mapping a property into a column. This kind of property is read only (its value is calculated by your formula fragment).

@Formula("obj_length * obj_height * obj_width")
public long getObjectVolume()

The SQL fragment can be as complex as you want and even include subselects.

...

5.1.7.1. Using a foreign key or an association table

...

Note

You can use a SQL fragment to simulate a physical join column using the @JoinColumnOrFormula / @JoinColumnOrformulas annotations (just like you can use a SQL fragment to simulate a property column via the @Formula annotation).

@Entity
public class Ticket implements Serializable {
    @ManyToOne
    @JoinColumnOrFormula(formula="(firstname + ' ' + lastname)")
    public Person getOwner() {
        return person;
    }
    ...
} 

Also, we should use insertable = false, updatable = false, because such mapping is not editable

Upvotes: 3

Related Questions