问题
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:
- Add property to persistence.xml:
property name="hibernate.session_factory.statement_inspector" value="full-qualified class name"
- 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