Turning off net.sf.ehcache and org.hibernate DEBUG logging - spring

I am getting a host of DEBUG messages from net.sf.ehcache and org.hibernate in my Spring (version 5.2.5.RELEASE) application. I am using version 5.2.10.Final of hibernate-ehcache. The messages look like this:
16:20:12.910 [RMI TCP Connection(3)-127.0.0.1] DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl - Mocking Operation Statistic: XA_COMMIT
16:20:12.910 [RMI TCP Connection(3)-127.0.0.1] DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl - Mocking Operation Statistic: XA_ROLLBACK
16:20:12.910 [RMI TCP Connection(3)-127.0.0.1] DEBUG net.sf.ehcache.statistics.extended.ExtendedStatisticsImpl - Mocking Operation Statistic: XA_RECOVERY
and also many like this:
1:14:39.284 [http-nio-8080-exec-3] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [com.acme.MyBean#145]
I've tried to turn them down by using this in log4j.xml
<logger name="net.sf.ehcache">
<level value="WARN"/>
</logger>
I've also tried this in application.properties:
logging.level.org.springframework.web=WARNING
logging.level.org.hibernate=ERROR
logging.level.org.springframework.cache=WARNING
But neither of these changes filters out the DEBUG messages.
Here is the ehcache configuration as defined in spring-config.xml:
<bean id="readOnlyDatabaseSessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.SQLServerDialect
</prop>
<prop key="hibernate.show_sql">${hibernate.debug}</prop>
<prop key="hibernate.format_sql">${hibernate.debug}</prop>
<prop key="hibernate.use_sql_comments">${hibernate.debug}</prop>
<prop key="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
</prop>
<prop key="net.sf.ehcache.configurationResourceName">
ehcache.xml
</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.default_batch_fetch_size">100</prop>
</props>
</property>
<property name="dataSource" ref="readOnlyDataSource"/>
</bean>
I have the following settings in application.properties:
# logging for hibernate
logging.level.org.hibernate.SQL=warn
logging.level.org.hibernate.stat=warn
logging.level.org.hibernate.type=warn
logging.level.org.springframework.web=WARN
logging.level.org.hibernate=ERROR
logging.level.org.springframework.cache=WARN
logging.level.root=WARN
logging.level.net.sf.ehcache=WARN
spring.jpa.properties.hibernate.generate_statistics=false
How do I turn off DEBUG messages for net.sf.ehcache and org.hibernate?

If you want to turn off the logging on a specific package you should use the value off. This will work both on package and class level like:
logging.level.org.hibernate.SQL=OFF
com.yourproject.util.SomeUtilsClass=OFF
Normally logging.level.net.sf.ehcache=WARN should work, but can you try:
logging.level.net.sf.ehcache.statistics.extended=WARN
If you're running a junit test you should update/create different config for that because by default junit will use DEBUG as the root log level where when you launch your springboot app it will use by default INFO and what you customized in your application.properties.

Welcome in the world of Open Source where you have many options to choose from, but documentation is scarce.
I don't know whether you use only Spring or also Spring Boot, how you start your application, and without having a reproducable scenario it is impossible to give a precise answer so here comes a bit longer and more complex answer:
application.properties might work if you use the right logging libraries (e.g. in pom.xml ) and the right way to initialize spring boot (which you probably don't use)
if you are sure that you use spring boot (dependencies + initialization) but your configuration files are ignored although the application is reading them it may be that you override the settings using e.g.: environment variables, see the 17 different ways to externalize configuration for spring boot 1.2
if you use maven you may want to get a clearer picture of which logging frameworks you use by executing some of these commands: mvn dependency:tree or mvn help:effective-pom or in any case look at the Java classpath for which files and directories your logging libraries and configuration files might be loaded from and read their respective documentation on how to configure them (which is very different e.g. for the non-backwards compatible log4j2 than for log4j 1.x, logback, etc.)
before you start pulling your hair in desperation because you really cannot find where your application tries to load logging configuration from, run a tracing tool for your operating system to see which files it opens and reads during startup, e.g.: strace (Linux), sysinternals process monitor (Windows) offer insight into the interaction between your application (Java) and the operating system
Finally, be aware that some logging frameworks (e.g.: log4j2, slf4j) have been split in multiple parts, e.g.:
for the programmer to program/compile against
for the runtime to write the logging to a file, over the network or to another logging framework
integration to also receive logging from other framworks
See for some great examples how you can use that:
for Log4j2 this documentation
for SLF4J/logback that documentation

Related

Setup JPA Console in Intellij using Spring

I'm trying to get the JPA console working in Intellij. I have added JPA to the project under facets. However, IDE is asking for a persistence.xml. I'm using Annotated Spring and don't have any direct mapping files. Anyone configured this before, and can help me? Thanks
Further information:
Without adding JavaEE stuff - I don't need this.
File->Project Structure - Under modules: add JPA to a single module. Do not add persistence.xml or orm.xml
Under facets: Add JPA. Leave XML config blank. Leave JPA Provider blank
View -> Tool windows -> Persistence
You will see the module name and the EntityManager as configured under your SpringContext.xml. On my system I have these properties referenced in this SpringContext.xml
# jdbc.X
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql:///someThing
jdbc.user=postgres
jdbc.pass=postgres
# hibernate.X
hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=create
I then select in my Persistence window (in which I can now see all entities) - click console button. Select JPA console. This will get me the error outlined here {yes, I'm using Postgres}
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206186929-JPA-Console-without-persistence-xml
Note the two "TTs-" PostgreSQL9Dialectt
Further further information:
Wierd. If I move the dialect into the actual xml config
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</prop>
<!--<prop key="hibernate.enable_lazy_load_no_trans">true</prop>-->
</props>
</property>
[2017-01-04 13:03:46] java.lang.IllegalStateException: Transaction already active
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
at com.intellij.jpa.remote.impl.RemoteQueryImpl$1.getResultList(RemoteQueryImpl.java:92)
at com.intellij.jpa.remote.impl.QueryResultImpl.ensureInitialized(QueryResultImpl.java:113)
at com.intellij.jpa.remote.impl.QueryResultImpl.getColumnInfos(QueryResultImpl.java:30)
at com.intellij.jpa.remote.impl.RemoteQueryResultImpl.getColumnInfos(RemoteQueryResultImpl.java:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

How to reuse spring integration beans in a single application?

I'm using spring integration to create multiple services (each running in their own JVM) with JMS endpoints.
Once retry, exception handling, etc is added, the configuration is no longer trivial. I have moved the spring integration into its own context file and import it in all services to have a consistent setup.
eg
<import resource="classpath:/spring/jmsEndpoint.xml"/>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties">
<props>
<prop key="queueName">myServiceQueue</prop>
</props>
</property>
</bean>
<alias name="myBusinessLogic" alias="abstractJmsEndpoint"/>
<bean id="myBusinessLogic" class="..."/>
This configuration allows me to keep each individual service configuration simple, only requiring an override of an abstract bean and setting a few properties.
The problem is I now want multiple jms endpoints in the same service (jvm). As I can't import jmsEndpoint.xml multiple times, what is the best way to reuse the configuration?
See the dynamic-ftp sample - it uses a technique of creating instances of a parameterized application contexts, passing different properries into each. It's README also has links to forum discussions about how to make these contexts children of the main context, in cases where the child needs access to shared resources.

Multi-tenant webapp using Spring MVC and Hibernate 4.2.0.Final

I have developed a small webapp using and SpringMVC(3.1.3.RELEASE) and Hibernate 4.2.0.Final.
I'm trying to convert it to be a multi-tenant application.
Similar topics have been covered in other threads, but I couldn't find a definitive solution to my problem.
What I am trying to achieve is to design a web app which is able to:
Read a datasource configuration at startup (an XML file containing multiple datasource definitions, which is placed outside the WAR file and it's not the application-context or hibernate configuration file)
Create a session factory for each one of them (considering that each datasource is a database with a different schema).
How can i set my session factory scope as session? ( OR Can i reuse the same session factory ?) .
Example:
Url for client a - URL: http://project.com/a/login.html
Url for client b - URL: http://project.com/b/login.html
If client "a" make request,read the datasource configuration file and Create a session factory using that XML file for the client "a".
This same process will be repeating if the client "b" will send a request.
What I am looking, how to implement datasource creation upon customer subscription without editing the Spring configuration file. It needs to be automated.
Here is my code ,that i have done so far.
Please anyone tell me,What modifications i need to be made?
Please give an answer with some example code..I am quite new in spring and hibernate world.
Spring.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}"
p:username="${jdbc.username}" p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
JDBC.properties File
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.dialect=org.hibernate.dialect.MySQLDialect
jdbc.databaseurl=jdbc:mysql://localhost:3306/Logistics
jdbc.username=root
jdbc.password=rot#pspl#12
hibernate.cfg.xml File
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="pepper.logis.organizations.model.Organizaions" />
<mapping class="pepper.logis.assets.model.Assets" />
</session-factory>
</hibernate-configuration>
Thanks,
First create a table for Tenant with tenant_id and associate it with all users.Now, you can fetch this details while the user logs in and set it in session.
We are using AbstractRoutingDataSource to switch DataSource for every request on Spring Boot. I think it is Hot Swapable targets/datasource mentioned by #bhantol above.
It solves our problems but I don't think it is sound solution. I guess JNDI could be a better one than AbstractRoutingDataSource.
Wondering what you ended up with.
Here are some ideas for you.
Option 1) Single Application Instance.
It is somewhat ambitious to to this using what you are actually trying to achieve.
The gist is to simply deploy the same exact application with different context root on the same JVM. You can still tune the JVM as a whole like you would have if you had a truely multi-tenant application. But this comes at the expense of duplication of classes, contexts, local caching, start up times etc.
But as of today the Spring Framework 4.0 does not provide much of an multi-tenancy support (other than Hot Swapable targets/datasource) etc. I am looking for a good framework but it may be a wash to move away from Spring at this time for me.
Option 2) Multiple deployments of same application (more practical as of today)
Just have your same exact application deploy to the same application server JVM instance or even different.
If you use the same instance you may now need to bootstrap your app to pickup a DataSource based on what the instance should serve e.g. client=a property would be enough to pickup a **a**DataSource" or **b**DataSource I myself ended up going this approach.
If you have a different application server instance you could just configure a different JNDI path and treat things generically. No need for client="a" property because you have liberty to define your datasource differently with the same name.

Hibernate datasource config based on login user credentials

I am developing a Java webapp with Spring 3.2.1 and Hibernate 4.1.9 tied to Postgres Advanced Server backend (for row level security). The problem I am trying to solve is how to tie the webapp login user to the to the Hibernate session. To be specific, if user A logs in, then I want the webapp connection to the database to use A' credentials (only then I will be able to filter records that A has permissions to view / alter). Webapp & database users are validated against the same ldap server.
My config info is as follows:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.mycom.proj.model.A</value>
<value>com.mycom.proj.model.B</value>
<value>com.mycom.proj.model.C</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
</bean>
Based on the above config, dataSource and sessionFactory beans are singleton's.
One approach I could take is to set the dataSource and sessionFactory to "session" scope. I am hesitant to take that approach for the following reasons:
a) If the database connection is at a session scope, then I cannot make use of connection pooling. (I think I may have to live with it)
b) I am afraid that setting the sessionFactory to session scope will mess up the Hibernate' cache mechanism.
Any thoughts / ideas about how I could solve this issue?
Thanks in advance.
Another alternative is to make all connections as an unprivileged user that has NOINHERIT membership of all the user roles. You then SET ROLE to the logged in user before running queries. If you fail to SET ROLE due to a programming error harm is minimized because you haven't granted the unprivileged user you're connecting with any rights and it hasn't inherited any, so it can't do anything.
It should be pretty easy to do this with servlet filters (if you use one connection for a whole request), CDI interceptors, a wrapper around your connection pool, using hooks provided by your connection pool implementation, or various other options to make sure it always happens.
It'd be nice if you could use SET SESSION AUTHORIZATION instead, but that requires a superuser connection. I don't recommend that applications use superuser connections even if they're just going to decrease their rights. One mistake could have very serious consequences.
I wrote in a lot more detail about this in response to a DBA question a while ago.
Usually connections pools handle per user pooled connections, so you only need an adapter to redirect getConnection() calls to getConnection(user, passwd).
Spring provides one, see: org.springframework.jdbc.datasource.UserCredentialsDataSourceAdapter
you can set the credentials on the Datasource via setCredentialsForCurrentThread() method in the login filter, for example.

Websphere, Spring, Hibernate, JAX-WS Global Transactions

I am attempting to write a demo of a JAX-WS service participating in a global transaction. This is a model my organization will be doing more of as time goes on and we need to figure it out, but I am struggling.
I have a WSDL service being invoked from a client (which is also in a Java EE servlet with the same config...in fact it is the same server, but I can see that it is calling out over the wire to itself). Both are updating their rows, and then I throw an exception but the service will not rollback.
I have annotated a method that invokes both a local DAO update and the WSDL service client with #Transactional(propagation=Propagation.REQUIRED). That service in turn invokes another method, also anotated in the same way, which in turn calls a dao method to do another db update.
app-config.xml:
<jee:jndi-lookup id="wsdlDataSource" jndi-name="${es.ds.jndi}" />
<bean id="wsdlSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="wsdlDataSource" />
<property name="packagesToScan" value="com.wsdl" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
<prop key="hibernate.connection.driver_class">com.ibm.db2.jcc.DB2Driver</prop>
<prop key="hibernate.bytecode.provider">javassist</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.default_schema">k702prdr</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</prop>
<prop key="jta.UserTransaction">java:comp/UserTransaction</prop>
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.wsdl.db.DBTrans</value>
<value>com.wsdl.db.UsrTrans</value>
</list>
</property>
</bean>
<!-- END Data sources -->
<!-- BEGIN Hibernate config and dependencies -->
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager" >
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
I have followed some tutorials that had me go in to the Services view and add the WSTRansaction policy sets and bindings o the client and service (both generated initially from the RAD wizard), and then again into Admin Console applications->application Types->Websphere enterprise apps->my app->Service provider/client policy sets and bindings. There I added WSTransaction to client and service respectively at the parent application level (the policy inherits down to the endpoint).
But at the end of the day, no rollback is happening. Help! What am I missing? What have I misconfigured?
(update) - I found how to turn on the websphere transaction trace log in the admin console. It says (edited for brevity):
No transaction context found
Exit
Entry parm0=Operation: isAlive
No transaction context from incoming request
getTransactionManager parm0=com.ibm.ws.tx.jta.TranManagerSet#306e306e
These messages come with a bunch of what appear to be inspections of objects, and they repeat many times. Okay, so I appear to not be sending a transaction context from my client. But I still don't understand why. Anyone?
(update 2) - I discovered that my WSTRansaction policy sets for the service and client was not set to share, so i set it to share via the wsdl, and the trace log now seems to indicate that it is finding the transaction context...or at least, it's no longer explicitly saying it can't as above. It is saying some things like the following that may or may not means what i think they mean (again, edited for brevity if there is something meaningful you are not seeing, tell me, there is alot more info in there):
Entry parm0=XATransactionWrapper# 5f175f17 XAResource: com.ibm.ws.rsadapter.spi.WSRdbXaResourceImpl#5b7d5b7d enlisted: falseHas Tran Rolled Back = false mcWrapper.hashCode()490085686 parm1=XARESOURCE_NOTASSOCIATED
xa_start with flag: 0=TMNOFLAGS
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my first update in the service]
setResourceStatus parm0=from REGISTERED to COMPLETING_ONE_PHASE
**setResourceStatus parm0=from COMPLETING_ONE_PHASE to COMMITTED**
setResourceStatus parm0=from NONE to REGISTERED
[at this point I see a log stmt that indicates my second update, which is done in the client]
setResourceStatus parm0=from REGISTERED to COMPLETING
setResourceStatus parm0=from COMPLETING to ROLLEDBACK
[at this point I see the stack trace of the hardcoded exception I am throwing]
So it seems pretty clear that while the transaction manager now sees both the client and service transaction, it thought it was supposed to complete the transaction on the service side as soon as that part was done, not realizing it was supposed to continue. Somehow I triggered a premature commit I guess. Ideas?

Categories

Resources