Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fire Hibernate custom event listener before auto-triggered default listeners

I made a custom Hibernate Event listener extending org.hibernate.event.PreInsertEventListener. The custom listener overrides onPreInsert method and sets a field of a "Contact" entity before saving it in DB with a DAO.

Problem is, the field was null before the listener gives it a value and default hibernate event listeners are automatically triggered BEFORE my custom listener. As they check the ddl, they see the not-null constraint on the field and throw a null check exception before letting my custom event listener give the field its value. (same problem happens when using spring AOP instead of hibernate custom listeners: the default hibernate listener is executed before my aspect method)

So, it is possible to tune the triggering order of the hibernate listeners knowing that I use a spring session factory ?

Thanks

like image 728
Jihed Amine Avatar asked May 30 '11 15:05

Jihed Amine


1 Answers

I have an example for you which creates data history for person entity. Hope it helps.

I had to make a helper interface:

public interface DataHistoryAware {

    public DataHistory getDataHistory();

    public void setDataHistory(DataHistory dataHistory);
}

This is the listener implementation:

public class DataHistoryListener {
   @PrePersist
    public void setCreateDataHistory(DataHistoryAware model) {
        //set creationDate
        DataHistory dataHistory = model.getDataHistory() == null ? new DataHistory() : model.getDataHistory();
        dataHistory.setCreationDate(new Date());
        model.setDataHistory(dataHistory); 
    }
@PostUpdate
    public void setUpdateDataHistory(DataHistoryAware model) {
        DataHistory dataHistory = model.getDataHistory() == null ? new DataHistory() : model.getDataHistory();
        dataHistory.setLastModificationDate(new Date());
        model.setDataHistory(dataHistory);
    }
}

The person entity:

@Entity
@EntityListeners(DataHistoryListener.class)
@Table(name="person")
public class Person implements Serializable, DataHistoryAware {

@Column(name = "full_name", length = 255, nullable = false)
    private String fullName;

@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "data_history_id", nullable = false)
private DataHistory dataHistory;

public String getFullName() {
        return this.fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
public DataHistory getDataHistory() {
        return dataHistory;
    }

    public void setDataHistory(DataHistory dataHistory) {
        this.dataHistory = dataHistory;
    }
}

This implementation creates a datahistory record for person entity before persist, and will update it before merge. The datahistory property has a not-null constraint, so this is the same thing like your problem with the not-null property of the contact entity. Hope it was useful.

like image 88
lepike Avatar answered Nov 07 '22 19:11

lepike