diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java new file mode 100644 index 0000000000..1d60ccb6c0 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptor.java @@ -0,0 +1,32 @@ +package com.baeldung.hibernate.interceptors; + +import java.io.Serializable; +import java.util.Date; + +import org.hibernate.EmptyInterceptor; +import org.hibernate.type.Type; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.baeldung.hibernate.interceptors.entity.User; + +public class CustomInterceptor extends EmptyInterceptor { + private static final Logger logger = LoggerFactory.getLogger(CustomInterceptor.class); + + @Override + public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { + if (entity instanceof User) { + logger.info(((User) entity).toString()); + } + return super.onSave(entity, id, state, propertyNames, types); + } + + @Override + public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object [] previousState, String[] propertyNames, Type[] types) { + if (entity instanceof User) { + ((User) entity).setLastModified(new Date()); + logger.info(((User) entity).toString()); + } + return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types); + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptorImpl.java b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptorImpl.java new file mode 100644 index 0000000000..a84a981f7f --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/CustomInterceptorImpl.java @@ -0,0 +1,122 @@ +package com.baeldung.hibernate.interceptors; + +import java.io.Serializable; +import java.util.Iterator; + +import org.hibernate.CallbackException; +import org.hibernate.EntityMode; +import org.hibernate.Interceptor; +import org.hibernate.Transaction; +import org.hibernate.type.Type; + +public class CustomInterceptorImpl implements Interceptor { + + @Override + public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { + // TODO Auto-generated method stub + return false; + } + + @Override + public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public void onCollectionRemove(Object collection, Serializable key) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public void preFlush(Iterator entities) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public void postFlush(Iterator entities) throws CallbackException { + // TODO Auto-generated method stub + + } + + @Override + public Boolean isTransient(Object entity) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getEntityName(Object object) throws CallbackException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object getEntity(String entityName, Serializable id) throws CallbackException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void afterTransactionBegin(Transaction tx) { + // TODO Auto-generated method stub + + } + + @Override + public void beforeTransactionCompletion(Transaction tx) { + // TODO Auto-generated method stub + + } + + @Override + public void afterTransactionCompletion(Transaction tx) { + // TODO Auto-generated method stub + + } + + @Override + public String onPrepareStatement(String sql) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/HibernateUtil.java new file mode 100644 index 0000000000..11dce698ca --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/HibernateUtil.java @@ -0,0 +1,79 @@ +package com.baeldung.hibernate.interceptors; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.Interceptor; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import com.baeldung.hibernate.interceptors.entity.User; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + private static String PROPERTY_FILE_NAME; + + public static SessionFactory getSessionFactory() throws IOException { + return getSessionFactory(null); + } + + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + if (sessionFactory == null) { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = getSessionFactoryBuilder(serviceRegistry).build(); + } + return sessionFactory; + } + + public static SessionFactory getSessionFactoryWithInterceptor(String propertyFileName, Interceptor interceptor) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + if (sessionFactory == null) { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = getSessionFactoryBuilder(serviceRegistry).applyInterceptor(interceptor) + .build(); + } + return sessionFactory; + } + + public static Session getSessionWithInterceptor(Interceptor interceptor) throws IOException { + return getSessionFactory().withOptions() + .interceptor(interceptor) + .openSession(); + } + + private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addPackage("com.baeldung.hibernate.interceptors"); + metadataSources.addAnnotatedClass(User.class); + + Metadata metadata = metadataSources.buildMetadata(); + return metadata.getSessionFactoryBuilder(); + + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate-interceptors.properties")); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java new file mode 100644 index 0000000000..2b1dbe702b --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/interceptors/entity/User.java @@ -0,0 +1,64 @@ +package com.baeldung.hibernate.interceptors.entity; + +import java.util.Date; + +import javax.persistence.Basic; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +@Entity(name = "hbi_user") +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + private String name; + private String about; + @Basic + @Temporal(TemporalType.DATE) + private Date lastModified; + + public User() { + } + + public User(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public long getId() { + return id; + } + + public String getAbout() { + return about; + } + + public void setAbout(String about) { + this.about = about; + } + + @Override + public String toString() { + return String.format("ID: %d\nName: %s\nLast Modified: %s\nAbout: %s\n", getId(), getName(), getLastModified(), getAbout()); + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java new file mode 100644 index 0000000000..cbf28497bb --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/interceptors/HibernateInterceptorTest.java @@ -0,0 +1,62 @@ +package com.baeldung.hibernate.interceptors; + +import java.io.IOException; +import java.io.Serializable; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.interceptors.entity.User; + +public class HibernateInterceptorTest { + private static SessionFactory sessionFactory; + private static Serializable userId; + + @Before + public void init() throws IOException { + sessionFactory = HibernateUtil.getSessionFactoryWithInterceptor(null, new CustomInterceptor()); + } + + @AfterClass + public static void finish() { + if(userId != null) { + Session session = sessionFactory.getCurrentSession(); + Transaction transaction = session.beginTransaction(); + User user = session.load(User.class, userId); + if(user != null) { + session.delete(user); + } + transaction.commit(); + session.close(); + } + } + + @Test + public void givenHibernateInterceptorAndSessionScoped_whenUserCreated_shouldSucceed() { + Session session = sessionFactory.withOptions().interceptor(new CustomInterceptor()).openSession(); + User user = new User("Benjamin Franklin"); + Transaction transaction = session.beginTransaction(); + userId = session.save(user); + transaction.commit(); + session.close(); + } + + @Test + public void givenHibernateInterceptorAndSessionFactoryScoped_whenUserModified_shouldSucceed() { + Session session = sessionFactory.openSession(); + Transaction transaction = session.beginTransaction(); + User user = session.load(User.class, userId); + if(user != null) { + user.setAbout("I am a scientist."); + session.update(user); + } + transaction.commit(); + session.close(); + } + +} diff --git a/hibernate5/src/test/resources/hibernate-interceptors.properties b/hibernate5/src/test/resources/hibernate-interceptors.properties new file mode 100644 index 0000000000..58b55d0a09 --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-interceptors.properties @@ -0,0 +1,10 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop +hibernate.current_session_context_class=org.hibernate.context.internal.ThreadLocalSessionContext \ No newline at end of file