我使用PreInsertEventListener
和PreInsertEventListener
事件侦听器在表格中插入创建日期和更新日期。
我面临的问题是,当我在数据库中保存实体时创建的日期无法插入表中,与更新记录时插入更新日期相同,它也不会插入更新日期。
我的代码示例显示如下:
听众类:
public class PreInsertListener implements PreInsertEventListener,
PreUpdateEventListener
{
@Override
public boolean onPreInsert(PreInsertEvent arg0) {
City.class.cast(arg0.getEntity()).setCreated_date(new Date());
return false;
}
@Override
public boolean onPreUpdate(PreUpdateEvent arg0) {
System.out.println("Update event......");
City.class.cast(arg0.getEntity()).setUpdated_date(new Date());
return false;
}
}
Hibernate Connection类:
public class HibernateUtil
{
private static final SessionFactory sessionFactory;
static {
try {
AnnotationConfiguration config = new AnnotationConfiguration();
config.setListener("pre-insert", new PreInsertListener());
config.setListener("pre-update", new PreInsertListener());
sessionFactory = config.configure().buildSessionFactory();;
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
DAO中的实体保存和更新方法:
public Long saveCity(String cityName)
{
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
Long cityId = null;
try {
transaction = session.beginTransaction();
City city = new City();
city.setName(cityName);
cityId = (Long) session.save(city);
//session.flush();
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
return cityId;
}
public void updateCity(Long cityId, String cityName)
{
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
City city = (City) session.get(City.class, cityId);
city.setName(cityName);
session.update(city);
//session.flush();
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
我的测试班:
public class Main
{
public static void main(String[] args) {
CityDAO cityDAO = new CityDAO();
long cityId1 = cityDAO.saveCity("New York");
cityDAO.updateCity(cityId1, "Paris");
}
}
如果我使用session.flush()
,它将插入创建和更新的日期,但每次调用flush方法时都会执行更新的查询。目前我评论了代码来调用代码中显示的session.flush()
方法。
这个问题的解决方案是什么?
答案 0 :(得分:3)
这样做
public class PreInsertListener implements PreInsertEventListener,
PreUpdateEventListener
{
@Override
public boolean onPreInsert(PreInsertEvent arg0) {
if(arg0.getEntity() instanceof City){
City city = (City)arg0.getEntity();
city.setCreated_date(new Date());
}
return false;
}
@Override
public boolean onPreUpdate(PreUpdateEvent arg0) {
if(arg0.getEntity() instanceof City){
City city = (City)arg0.getEntity();
city.setCreated_date(new Date());
}
return false;
}
}
答案 1 :(得分:2)
我创建了Interceptor,用Hibernate EmptyInterceptor扩展它
覆盖方法onSave()
将在保存对象时调用,该对象尚未保存到数据库中,onFlushDirty()
在更新对象时调用该对象,该对象尚未更新到数据库中。
在这个函数中,我通过其名称检查我的方法,我必须在创建或更新时设置日期
这是onFlushDirty()方法的示例代码。
public boolean onFlushDirty(Object entity,Serializable id,Object[] currentState,
Object[] previousState,String[] propertyNames, Type[] types)
{
if ( entity instanceof City ) {
for ( int i=0; i < propertyNames.length; i++ ) {
if ( "lastUpdatedOn".equals( propertyNames[i] ) ) {
currentState[i] = new Date();
return true;
}
}
}
return false;
}
此处lastUpdatedOn
是我的方法名称,用于设置更新的记录日期。
onSave()方法:
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types)
{
if ( entity instanceof City) {
for ( int i=0; i<propertyNames.length; i++ ) {
if ( "createdOn".equals( propertyNames[i] ) ) {
state[i] = new Date();
return true;
}
}
}
return false;
}
此处createdOn
是设置记录创建日期的方法。
使用此拦截器类扩展您的POJO类。
答案 2 :(得分:0)
当我集成Spring4和Hibernate5时,我最近遇到了同样的问题。 这是我的BaseEntity类。
List<IMessage> Messages = new List<IMessage>(){new SmsMessage("SomeText"),
EmailMessage("Hi!", "To Brad Pitt")};
首先,您需要定义EntityListener类。
@MappedSuperclass
public class BaseEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, updatable = false)
private Date createDate;
@Column(nullable = false)
private Date modifyDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
然后,您应该注册实体事件监听器。
public class EntityListener implements PreInsertEventListener, PreUpdateEventListener {
private static final String CREATE_DATE_PROPERTY = "createDate";
private static final String MODIFY_DATE_PROPERTY = "modifyDate";
@Override
public boolean onPreInsert(PreInsertEvent event) {
if (event.getEntity() instanceof BaseEntity){
//property name of entity
String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames();
//property value of entity
Object[] state = event.getState();
for (int i = 0; i < propertyNames.length ; i ++) {
if (CREATE_DATE_PROPERTY.equals(propertyNames[i]) || MODIFY_DATE_PROPERTY.equals(propertyNames[i])){
state[i] = new Date();
}
}
}
return false;
}
@Override
public boolean onPreUpdate(PreUpdateEvent event) {
if (event.getEntity() instanceof BaseEntity){
//property name of entity
String[] propertyNames = event.getPersister().getEntityMetamodel().getPropertyNames();
//property value of entity
Object[] state = event.getState();
for (int i = 0; i < propertyNames.length ; i ++) {
if (MODIFY_DATE_PROPERTY.equals(propertyNames[i])){
state[i] = new Date();
}
}
}
return false;
}
}
效果很好,我希望它对你有所帮助。