Перехватчики гибернации с аннотациями - PullRequest
5 голосов
/ 24 августа 2011

Я перевожу приложение из конфигурации hibernate xml на аннотации, я не уверен, как адаптировать мой класс BusinessObjectInterceptor к новому формату на основе аннотаций.

Мы изменяем наш класс HibernateUtil с создания SessionFactory

            InitialContext ctx      = new InitialContext();
        sessionFactory  = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory");

для создания EntityManagerFactory

            entityManagerFactory = Persistence.createEntityManagerFactory("primary");

Мы изменяем наш класс HibernateUtil с использования sessionFactory.openSession () на создание сеанса из EntityManager

            //s = sessionFactory.openSession(new BusinessObjectInterceptor());
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        s = entityManager.unwrap(Session.class);

.проблема в том, что я не уверен, как внедрить BusinessObjectInterceptor в новый сеанс Hibernate или как правильно аннотировать мои классы, чтобы они могли использовать Interceptor

Я пытаюсь установить Interceptor в качестве свойствав файле persistence.xml.Я не уверен, если это правильно*

@Entity
@Table(name="server_settings")
public class ServerSettings  extends BusinessObject
{
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer serverSettingsID;
    @Column(name = "email_server")
    private String emailServer;
    @Column(name = "email_from_address")
private String emailFromAddress;
    @Column(name = "email_user")
private String emailUser;
    @Column(name = "email_password")
private String emailPassword;

У нас есть класс BusinessObjectInterceptor и класс BusinessObject.Я опубликую их ниже для справки.Я думаю, что должно произойти, это то, что класс BusinessObject должен быть аннотирован, я не уверен, как это сделать, так как BusinessObject не сопоставляется со столбцами в определенной таблице, а столбцами, которые являются общими для всех таблиц в нашей базе данных.Я вставлю эти два класса ниже.Буду признателен за любые советы о том, как настроить мой перехватчик с аннотациями.Спасибо.

BusinessObjectInterceptor

public class BusinessObjectInterceptor extends EmptyInterceptor
{
private int updates;
private int creates;

private static final String defaultDesignation = "system";

private String getUserDesignation()
{
    UserContextI theContext = PersistenceContext.getUserContext();
    if (theContext == null) return defaultDesignation;
    String uid = theContext.getUserDesignation();
    if (uid == null) return defaultDesignation;
    return uid;
}
public boolean onFlushDirty(Object entity,
                            Serializable id,
                            Object[] currentState,
                            Object[] previousState,
                            String[] propertyNames,
                            Type[] types)
{
    boolean theReturn = false;
    if (entity instanceof BusinessObject)
    {
        updates++;
        for (int i=0; i<propertyNames.length; i++)
        {
            if ("changedDate".equals(propertyNames[i]))
            {
                currentState[i] = new Date();
                theReturn = true;
            }
            if ("changedBy".equals(propertyNames[i]))
            {
                currentState[i] = getUserDesignation();
                theReturn = true;
            }
        }
    }
    return theReturn;
}
public boolean onSave(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types)
{
    boolean theReturn = false;
    if (entity instanceof BusinessObject)
    {
        creates++;
        for (int i=0; i<propertyNames.length; i++)
        {
            if ("createdDate".equals(propertyNames[i]))
            {
                state[i] = new Date();
                theReturn = true;
            }
            if ("createdBy".equals(propertyNames[i]))
            {
                state[i] = getUserDesignation();
                theReturn = true;
            }
            if ("changedDate".equals(propertyNames[i]))
            {
                state[i] = new Date();
                theReturn = true;
            }
            if ("changedBy".equals(propertyNames[i]))
            {
                state[i] = getUserDesignation();
                theReturn = true;
            }
        }
    }
    return theReturn;
}
public void preFlush(Iterator entities)
{
    updates = 0;
    creates = 0;
}

BusinessObject

    public abstract class BusinessObject
{
private String status;
private String createdBy;
private Date   createdDate;
private String changedBy;
private Date   changedDate;
private int    updateCounter;

/**
 * Generic save method to be used for persisting a business object.
 * 
 * @return a copy of this business object in its saved state.
 * 
 * @throws Exception
 */
public BusinessObject save() throws Exception 
{
    Session        hsession = null;
    Transaction    tx = null;
    BusinessObject theObject = null;

    validate(); // throws ValidationException

    try {
        hsession = HibernateUtil.currentSession();
        tx = hsession.beginTransaction();

        if (getStatus() == null || getStatus().length() < 1)
        {
            setStatus("OK");
        }

        //theObject = (BusinessObject) hsession.saveOrUpdateCopy(this);
        theObject = (BusinessObject) hsession.merge(this);
        if (tx != null && tx.isActive() && !tx.wasCommitted())
            tx.commit();
    } catch (Exception e){
        try
        {
        if (tx!=null) tx.rollback();
        } catch (Exception e3)
        {}
        try
        {
        hsession.close();
        } catch (Exception e2)
        {}
        throw e;
    } finally
    {
        HibernateUtil.closeSession();
    }
    return theObject;
}

1 Ответ

1 голос
/ 15 ноября 2014

В JPA вы можете использовать аннотации @ PrePersist и @ PreUpdate для аннотирования метода в вашей модели (класс @Entity), который будет вызываться перед сохранением (INSERT) или обновление (UPDATE).

Вы можете создать прослушиватель сущностей и добавить @ EntityListeners аннотацию к своим моделям, например:

public class BusinessListener {
    @PrePersist
    public void businessUpdate(BusinessObject obj) {
        obj.setCreatedDate(new Date());
        ....
    }
    @PreUpdate
    public void businessUpdate(BusinessObject obj) {
        obj.setChangedDate(new Date());
        ....
    }
}

@EntityListeners(class=...BusinessListener)
public class BusinessObject {
}

Или вы можете поместить методы в базовый класс сущностей и расширить все ваши сущности из него, например:

public class BusinessObject {
    @PrePersist
    public void businessUpdate() {
        createdDate = new Date();
        ....
    }
    @PreUpdate
    public void businessUpdate() {
        changedDate = new Date();
        ....
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...