2015-03-11 4 views
1

Почти во всех классах Entity в моем приложении есть поле Timestamp для сохранения времени, когда Пользователь был изменен пользователем. Для этого поведения я использую простой метод, аннотированный @PreUpdate, чтобы установить значение этого поля в текущий java.util.Date.Редактирование объекта без выполнения метода @PreUpdate

Эта базовая функциональность исключается в некоторый класс BasicEntity, который я расширяю для конкретной реализации. Так что в основном выглядит следующим образом:

@MappedSuperclass 
public abstract class BasicEntity { 
    // ... 
    @PreUpdate 
    public void preupdate() { 
     this.lastupdate = new java.util.Date(); 
    } 
} 

@Entity 
public class User extends BasicEntity { 
    private java.util.Date lastlogin; 
} 

Теперь у меня есть требование не только сэкономить время последнего действия обновления, но и время, когда пользователь входит в систему в систему. Итак, в настоящее время, с моим методом входа в систему, я устанавливаю поле для последнего входа в текущую дату и сохраняю текущее состояние этого экземпляра пользователя через EntityManager. Но тогда, конечно, поле для последнего обновления также устанавливается из-за моего метода @PreUpdate.

Я не хочу, чтобы это произошло в этом конкретном случае! Как-то я хочу иметь возможность изменить значение поля lastlogin, не изменяя значение поля lastupdate.

У вас есть предложение, как я мог бы добиться этого в этом случае? Из-за большого количества дополнительных функций, предоставляемых BasicEntity, я хотел бы избежать возврата от его расширения.


Текущая попытка:

@MappedSuperclass 
public abstract class BasicEntity { 
    // ... 
    @PreUpdate 
    public void preupdate() { 
     this.lastupdate = new java.util.Date(); 
    } 
} 

@Entity 
public class User extends BasicEntity { 
    @Transient 
    protected volatile transient boolean login = false; 

    @Override 
    @PreUpdate 
    public void preupdate() {    
     if (!login) { 
      super.preupdate(); 
     } 
     login = false; 
    } 
} 

В моем Входе-методе, который я делаю следующее:

getUser().setLogin(true);  
userFacade.edit(getUser()); 

Но теперь, когда метод preupdate() Пользователь выполняется, значение login по-прежнему false.

+0

Я бы создал новую сущность 'UserLogin', с помощью множества-к-одному для вашего объекта' User' и вместо этого вставлял в нее значения для логинов. –

+0

Не будет ли это ссылаться на некоторую операцию em.merge на 'User' в любом случае и, таким образом, вызвать метод' @ PreUpdate'? – stg

ответ

1

Вы можете сделать что-то вроде этого:

@MappedSuperclass 
    public abstract class BasicEntity { 
     // ... 
     @Transient 
     protected volatile transient boolean updated = true;   

     @PreUpdate 
     public void preupdate() { 
      if(updated){ 
      this.lastupdate = new java.util.Date(); 
      } 
     } 
    } 

    @Entity 
    public class User extends BasicEntity { 
     private java.util.Date lastlogin; 

    public void setLastLogin(Date lastlogin){ 
     this.lastlogin = lastlogin; 
     this.updated = false; 
    } 

} 
+0

Большое спасибо, я думаю, я попытаюсь изменить этот подход таким образом, что я переоцениваю свой метод @PreUpdate в User, но в целом это звучит неплохо! – stg

+0

Рад помочь :) – Panchitoboy

+1

Поле обновления должно быть отмечено кратковременным и неустойчивым (как @Transient, так и временным). –

0

К сожалению, подход с использованием переходного поля здесь не работает в соответствии с проектом спецификации. См. Также this answer.

Я закончил тем, что использовал уродливый хак. Это мое окончательное решение:

Внутри Логин-метод:

getUser().setLastlogin(DateUtil.LOGIN);     
userJpa.edit(getUser()); 

Entity Класс:

@Override 
@PreUpdate 
public void preupdate() {  
    if (lastlogin != null && !lastlogin.equals(DateUtil.LOGIN)) {    
     super.preupdate(); 
    } 
    else { 
     lastlogin = new java.util.Date(); 
    } 
} 

LOGIN просто постоянный экземпляр Дата здесь, который я использую, чтобы решить, хочу ли я для выполнения метода PreUpdate Суперкласса или нет. Не очень приятно, но в производстве использовать в работах.

Смежные вопросы