How I can configure StatementInspector in Hibernate?

守給你的承諾、 提交于 2019-11-28 02:01:59

问题


https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Interceptor.html says that onPrepareStatement(String sql) is Deprecated. Supply a StatementInspector instead, if you wish to inspect and alter SQL statements.

But I am not clear how I can configure StatementInspector in Hibernate at application level (i don't want to set it at each hibernate session level).


回答1:


Don't do like that )

You need only two things:

  1. Add property to persistence.xml:

property name="hibernate.session_factory.statement_inspector" value="full-qualified class name"

  1. Write your listener class by implementing interface org.hibernate.resource.jdbc.spi.StatementInspector.

Profit!




回答2:


As I explained in this article, the best way to register a StatementInspector is to use the hibernate.session_factory.statement_inspector configuration property.

This way, it does not matter whether you are bootstrapping Hibernate using JPA (e.g. Spring Data JPA) or native Hibernate (e.g. Spring with HibernateTranscationManager and LocalSessionFactoryBean).

So, you can to provide the hibernate.session_factory.statement_inspector via the persistence.xml JPA configuration file:

<property
    name="hibernate.session_factory.statement_inspector"
    value="com.vladmihalcea.book.hpjp.hibernate.logging.inspector.SqlCommentStatementInspector"
/>

Or, you can also set the hibernate.session_factory.statement_inspector programmatically if you're using Spring:

@Bean
public LocalSessionFactoryBean sessionFactory() {
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setPackagesToScan({
        "com.vladmihalcea.books.high.performance.java.persistence"
    });
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager
      = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

private final Properties hibernateProperties() {
    Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty(
      "hibernate.session_factory.statement_inspector", 
      SqlCommentStatementInspector.class
    );
    hibernateProperties.setProperty(
      "hibernate.dialect", 
      "org.hibernate.dialect.H2Dialect"
    );

    return hibernateProperties;
}

Notice that the hibernate.session_factory.statement_inspector setting can take either a String representing he fully-qualified class implementing the StatementInspector interface, a Class<? extends StatementInspector> or a StatementInspector object reference.




回答3:


In order to get this to work, you have to bootstrap Hibernate. To do this:

In your main class, find your EntityManagerFactory instance. It probably looks something like this:

public static final EntityManagerFactory EMPFAC = Persistence.createEntityManagerFactory("jpa")

Leave that line for now. Above it, add the following:

private static StandardServiceRegistryBuilder servReg = new StandardServiceRegistryBuilder();
static {
    //Do this for every property in persistence.xml
    servReg.applySetting("hibernate.connection.url", "jdbc://myurl://www.example.org");
}

Add a servReg.applySetting() for every property in persistence.xml. Then, add this below it:

private static MetadataSources sources = new MetadataSources(servReg.build());
static {
    // Do this for every pojo with JPA annotations
    sources.addAnnotatedClass(Pojo.class);
}

Add a sources.addAnnotatedClass() for every JPA-annotated pojo in your application. Almost done here. Now create a class that implements StatementInspector like so:

public class Inspector implements StatementInspector {

    private static final long serialVersionUID = 5545844969759630544L;

   @Override
   public String inspect(String select) {
       // modify string here
       return select;
   }
}

Finally, go back to your main application class, and, underneath the static block where you registered your pojos, add the following:

public static final SessionFactory EMPFAC = sources.buildMetadata().getSessionFactoryBuilder().applyStatementInspector(new Inspector()).build();

Now you can go back to persistence.xml and delete the property declarations there. If you haven't already, also delete your public static final EntityManager declaration (you've replaced it with the SessionFactory).

EDIT: You can actually delete persistence.xml and your application should still work fine.

All set!



来源:https://stackoverflow.com/questions/39112308/how-i-can-configure-statementinspector-in-hibernate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!