gpt4 book ai didi

java - hibernate 中的 PreInsert 和 PreUpdate 事件监听器

转载 作者:行者123 更新时间:2023-11-30 06:21:34 24 4
gpt4 key购买 nike

我已经使用 PreInsertEventListenerPreUpdateEventListener 事件监听器在表中插入创建日期和更新日期。
我面临的问题是,当我在数据库中保存实体时,创建日期无法插入表中,就像在更新记录时插入更新日期一样,它也不会插入更新日期。

我的代码示例如下所示:

监听类:

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 连接类:

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() 方法,如代码所示。

这个问题的解决方案是什么?

最佳答案

我最近在集成 Spring4 和 Hibernate5 时遇到了同样的问题。这是我的 BaseEntity 类。

@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;
}
}

首先,您需要定义 EntityListener 类。

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;
}
}

然后,您应该注册实体事件监听器。

@SuppressWarnings("unchecked")
@Component
public class EntityEventListenerRegistry {

@Autowired
private SessionFactory sessionFactory;

/**
* EventListenerRegistry:http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#annotations-jpa-entitylisteners
*/
@PostConstruct
public void registerListeners(){
EventListenerRegistry eventListenerRegistry = ((SessionFactoryImplementor) sessionFactory).getServiceRegistry().getService(EventListenerRegistry.class);
eventListenerRegistry.prependListeners(EventType.PRE_INSERT, EntityListener.class);
eventListenerRegistry.prependListeners(EventType.PRE_UPDATE, EntityListener.class);
}

}

效果很好,希望对你有帮助。

关于java - hibernate 中的 PreInsert 和 PreUpdate 事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20368551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com