We use Hazelcast as our Hibernate 2nd level cache manager and we have some configurations for it in our Spring context files. Our code is also instrumented by Spring #Cacheable annotations (for business level cache) and we configured it to use Hazelcast. The problem is that in development environment we have multiple database instances and sometimes we should switch our application between them. Each time we switch to another database we should also restart the Hazelcast to be filled with new data and it is a REALY annoying work :(( This is more annoying when we need to have multiple instances of our application up on different databases! so we need also multiple instances of Hazelcast!!
As our code is tightly coupled with cache stuffs, it is so hard to remove cache configurations from the code for new instances. Is there any way to tell Hazelcast, Spring and Hibernate do not use/fill cache in presence of our configurations?
You should be able to turn off caching with the Spring and Hibernate configurations. In case of Spring Boot, you can do it by setting the following properties in your application-dev.properties:
spring.cache.type=NONE
spring.jpa.properties.hibernate.cache.use_second_level_cache=false
Related
We use a WebApplicationInitializer to decide the relevant Spring profile based on local properties
We want to decide on spring profile based on database table (one central place)
The issue is that not all beans are initialized, can it be done in a straight way?
Is it a good approach or anti-pattern/wrong to load spring profile from database ?
Note we already use #Order(1) in our classes
I found old related question but without any solution
In ApplicationContextInitializer I cannot use Spring beans because the application context is not yet fully initialized. Is low level access to the database my only option?
There's option to keep a cluster servers which will load database and then all servers will get profile using cluster, but it seems like a overhead
Scenario:
I'm supporting an Enterprise application that runs in Wildfly10. The application (.war) uses J2EE technologies (EJBs, JPA, JAX-RS) and SpringBoot features (like, SpringMVC, SpringRest, SpringData, SpringRestData) ... Both stacks co-exists "happily" because they don't interact between them; however, they do share common classes, like utility or Entity Classes (the stacks map to the same database model). Why the application uses those stacks is out the scope of the question.
Currently, I'm trying to improve the performance of a #RestController that pulls some data from the database using a JPA Spring Repository. I found that we're suffering the N + 1 queries problem when calling the #RestController. In past projects (where there were only J2EE technologies), I have used the #BatchSize hibernate annotation to mitigate this problem with total success.
But, in this project, Spring seems to be skipping such annotation. How do I know that? Because I turned on the hibernate SQL logging (hibernate.show_sql) and I can see the N + 1 queries is still happening ...
Key Points:
Here are some insights about the application that you must know before providing (or trying to guess) any answer:
The application has many sub-modules encapsulated as libraries inside WAR file (/WEB-INF/lib) ... Some of these libraries are the jars that encapsulate the entity classes; others are the jars that encapsulate the REST Services (that could be JAX-RS services or Spring Controllers).
The Spring configuration is done in the classes defined in the WAR artifact: in there, we have a class (that extends from SpringBootServletInitializer) annotated with #SpringBootApplication and another class (that extends from RepositoryRestConfigurerAdapter) annotated with #Configuration. Spring customization is done is such class.
The application works with multiple datasources, which are defined in the Wildly server. Spring DATA JPA must address any query pointing to the right datasource. To accomplish this requirement, the application (Spring) was configured like this:
#Bean(destroyMethod="")
#ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
// the following class extends from AbstractRoutingDataSource
// and resolve datasources using JNDI names (the wildfly mode!)
return new DataSourceRouter();
}
#Bean("entityManagerFactory")
public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean lemfb;
lemfb = new LocalContainerEntityManagerFactoryBean();
lemfb.setPersistenceUnitName("abcd-pu");
lemfb.setDataSource(dataSource());
return lemfb;
}
The last #Bean declaration favors the use of a persistence.xml file, which we do have in the route /WEB-INF/classes/META-INF/ (i.e. Spring does find this file!) ... In such file, we define our domain classes, so that Spring JPA can see such entities. Also, we can define special JPA properties like: hibernate.show_sql and hibernate.use_sql_comments without issues (this is how I detected the N + 1 queries problem in the first place) ...
What I have done so far?
I tried to add the #BatchSize annotation to the problematic collection. No luck!
I created a new JAX-RS Service whose purpose was to mimic the behavior of the #RestController. I confirmed that the #BatchSize annotation does work in the application's deployment, at least, in JAX-RS Services! (NOTE: the service uses it own persistence.xml) ...
Test details (Updated 2020/07/30): What I did here was to create a new JAX-RS Service and deployed it inside the WAR application, next to the #RestController that presents the problem (I mean, it is the same WAR and the same physical JVM). Both services pull from database the same entity (same class - same classloader), which has a lazy Collection annotated with #BatchSize! ... If I invoke both services, the JAX-RS honors the #BatchSize and pulls the collection using the expected strategy, the #RestController does not ... So, what it is happening here? The only thing different between the services is that each one has a different persistence.xml: the persistence.xml for the JAX-RS is picked by Wildfly directly, the other one is picked by Spring and delegated to Wildfly (I guess) ...
I tried to add the properties: hibernate.batch_fetch_style (=dynamic) and hibernate.default_batch_fetch_size (=10), to the persistence.xml read by Spring ... No luck. I debug the Spring startup process and I saw that such properties are passed to the Spring Engine, but Spring does not care about them. The weird thing here is that properties like: hibernate.show_sql, Spring does honor them ... For those who are asking: "What does these properties do?" Well, they are global equivalent to apply #BatchSize to any JPA lazy collection or proxy without declaring such annotation in any entity.
I setup a small SpringBoot Project using the same Spring version as enterprise application (which is 1.5.8.RELEASE, by the way) and both the annotation and properties approach worked as supposed to.
I've been stuck with this issue for two days, any help to fix this will be appreciated ... thanks!
There are 2-3 possible issues that I can think off.
For some reason, whatever you modify isnt picked up by wildfly - Wildfly classpath resolution is a separate Topic and some missing configuration can cause you a nightmare. This you can identify if you have access to debug the query, and in if you put a breakpoint in the constructor of your Entity class, you will get a chance to evaluate the entity configuration being used, somewhere in the execution conetxt.
BatchSize doesnt work on OneToOne, It only works on OneToMany relationships.
A typical way to define BatchSize is to do along with Lazy load as mentioned in the example here. If you are not using Lazy fetch, hibernate assumes that you are willing to make an eager load and makes another select query to fetch all the details.Please confirm you are using the same syntax as given in the example above.
New Addition:
Put Conditional Breakpoints in PropertyBinder#setLazy() function, and may be backtrace it and put relavent breakpoints in CollectionBinder and AnnotationBinder. then restart/redeploy the server and see what data you are getting for the relavent properties. That will give you fair idea where it is failing..
Why conditional breakpoint? Its because you will have thousands of properties and if you do not add condition to the breakpoint, you will take 1 hour to reach your actual breakpoint
What should be the condition - If its property binder, the condition shoud be like `this.name == . For other classes also you can use the same approach.
Sorry for too detailed description on conditional breakpoints, you might find it redundent.
Looks like the only way to debug your problem is to debug hibernate framework from server startup, then only we will be able to find out the rootcause
I'm currently developing a web application using Spring MVC (without Maven).
What I need is to create a distributed transaction between two local databases, so that the code will update all of them in (theoretically) a 2phase commit.
Now, since I'm doing it for a school project, I'm in a simple environment which needs only to take a row from a table in one db and put it in a table on the other db, of course atomically (theoretically, such a transaction should be distributed because I'm using two different databases and not only one).
My question is, how can I deploy a Spring bean that firstly connects to both MySQL databases and then does that distributed transaction? Should I use some external library or could I achieve all with only using the Spring framework? In which case, could you please kindly link me an example or a guide to do this?
Thank you in advance for your help :)
Spring has an interface PlatformTransactionManager which is an
abstraction And it has many implementations like
DataSourceTransactionManager,HibernateTransactionManager etc.
Since you are using distributed transactions so you need to use
JTATransactionManager
These TransactionManagers provided by spring
are wrapper around the implementations provided by other frameworks
Now in case of JTA , you would be using either an application server
or a standalone JTA implementation like Atomikos
Following are the steps :-
Configure Transaction Manager in spring using application server
or standalone JTA implementation
Enable Transaction Management in spring
And then configure in your code the #Transactional annotation above
your method
Have a look at following links
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html
http://www.byteslounge.com/tutorials/spring-jta-multiple-resource-transactions-in-tomcat-with-atomikos-example
I am developing a Spring Boot application that uses Spring Data JPA and will need to connect to many different databases e.g. PostreSQL, MySQL, MS-SQL, MongoDB.
I need to create all datasources in runtime i.e. user choose these data by GUI in started application:
-driver(one of the list),
-source,
-port,
-username,
-password.
And after all he writes native sql to choosen database and get results.
I read a lot of things about it in stack and spring forums(e.g. AbstractRoutingDataSource) but all of these tutorials show how to create datasources from xml configuration or static definition in java bean. It is possible to create many datsources in runtime? How to manage transactions and how to create many sessionFactories? It is possible to use #Transactional annotation? What is the best method to do this? Can someone explain me how to do this 'step by step'?
Hope it's not too late for an answer ;)
I developed a module which can be easily integrated in any spring project. It uses a meta-datasource to hold the tenant-datasource connection details.
For the tenant-datasource an AbstractRoutingDataSource is used.
Here you find my core implementation using the AbstractRoutingDataSource.
https://github.com/Dactabird/multitenancy
Here is an example to show how to integrate it. https://github.com/Dactabird/multitenancy-sample
In this example I'm using H2 embedded db. But of course you can use whatever you want.
Feel free to modify it for your purposes or to ask if questions are left!
I am planning an application that must provide services that are very much like those of a Java EE container to third party extension code. Basically, what this app does is find a set of work items (currently, the plan is to use Hibernate) and dispatch them to work item consumers.
The work item consumers load the item details, invoke third party extension code, and then if the third party code did not fail, update some state on the work item and commit all work done.
I am explicitly not writing this as a Java EE application. Essentially, my application must provide many of the services of a container, however; it must provide transaction management, connection pooling and management, and a certain amount of deployment support. How do I either A) provide these directly, or B) choose a third party library to provide them. Due to a requirement of the larger project, the extension writers will be using Hibernate, if that makes any difference.
It's worth noting that, of all of the features I've mentioned, the one I know least about is transaction management. How can I provide this service to extension code running in my container?
Hi I recommend using the Spring Framework. It provides a nice way to bring together a lot of the various services you are talking about.
For instance to address your specific needs:
Transaction Management/Connection pooling
I built a spring-based stand-alone application that used Apache commons connection pooling. Also I believe spring has some kind of transaction mgmt built in.
Deployment support
I use ant to deploy and run things as a front-loader. It works pretty well. I just fork a seperate process using ant to run my Spring stand-alone app.
Threading.
Spring has support for Quartz which deals well with threads and thread pools
DAO
Spring integrates nicely with Hibernate and other similar projects
Configuration
Using its xml property definitions -- Spring is pretty good for multiple-environment configuration.
Spring does have transaction management. You can define a DataSource in your application context using Apache DBCP (using a org.apache.commons.dbcp.BasicDataSourceorg.springframework.jdbc.datasource.DataSourceTransactionManager for the DataSource. After that, any object in your application can define its own transactions programatically if you pass it the TransactionManager, or you can use AOP interceptors on the object's definition in your application context, to define which methods need to be run inside a transaction.
Or, the easier approach nowadays with Spring is to use the #Transactional annotation in any method that needs to be run inside a transaction, and to add something like this to your application context (assuming your transactionManager is named txManager):
<tx:annotation-driven transaction-manager="txManager"/>
This way your application will easily accept new components later on, which can have transaction management simply by using the #Transactional annotation or by directly creating transactions through a PlatformTransactionManager that they will receive through a setter (so you can pass it when you define the object in your app context).
You could try Atomikos TransactionsEssentials for Java transaction management and connection pooling (JDBC+JMS) in a J2SE environment. No need for any appservers, and it is much more fun to work with ;-)
HTH
Guy