Managing hibernate entities in EJB project - java

I made an 'Enterprise application' in NetBeans and I added hibernate as well as some hibernate mapping files to the web application project. Additionally, I need to add a 'HibernateUtil.java', 'hibernate.cfg.xml' and 'hibernate.reveng.xml' in the web application.
However I wanted to manage these entity/mapping classes in my EJB project as they seem to behave like enterprise beans and I wanted to separate them from my web application. I was wondering how this can be done and how I could access the entities ejb's in my web application project through dependency injection? There was also an option in the 'New' menu: 'Create session bean for Entity classes' and wondered if it has any use in relation to the question?
EDIT: Using EJB3

You shouldn't have put your JPA-related files to a WAR at the first place. Keep them in EJB JAR and reference your JAR from WAR as a provided runtime dependency in Maven (or use provided scope's analogue for whichever build tool you prefer). Keeping your business logic in EJB JAR will pay off when you'll need more than one WAR in your EAR (different security realms, etc.)
In general, this is as simple as putting all your JPA-related stuff in EJB JAR, they will then be available for dependency injection from WAR-provided managed beans as well.
Also, consider replacing your Hibernate-specific configurations with JPA and let application server to resolve all the stuff for you.

Related

Dynamically loading Spring Beans and Components in Spring Boot

I'm trying to make a Spring Boot app where plugins are loaded dynamically from JARs at runtime. I also want the plugins to have access to all the Spring Boot features, most prominently Spring Data JPA. I've already figured out how to load classes from JARs, and now my problem is how to "hook up" the loaded classes (that might be Beans, JpaRepositories etc.) to "work with" my main Spring Boot application.
I also might in the future want to have my own annotation system for doing different things with the main app from the plugins, (that I know how to do using reflection) and I would want to still be able to do it after I manage to sort the Spring stuff out.
I imagine I have to tell Spring somehow to additionally look for #Components and other meaningful classes from those JARs, when it's scanning for annotations. I tried with #ComponentScan's basePackageClasses attribute but that needs to be constant, and hard-coding this is not an option for what I wanna do.
So is what I want to achieve even possible? And if it is, then can I do it through Java code, or is it maybe achievable by writing some XML configs?
When you start an spring app, beans are loaded and hooked in its contexts, so if you want to add more to it manually you might need to reload the whole context which may not be a good idea for an spring boot app.
Instead, I would suggest to use spring profiles, so you can define different configurations and based on what you want you can simple enable the one you need.
Find out more at:
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-profiles
Hope this helps!

How to reuse classes in a Spring Boot REST application?

I have a Spring Boot REST application with JPA entities and Repository classes (and related services) that works very well. Now I would like to reuse these classes for other purposes, like weekly CRON jobs and similar one-time processes which will be run from the command line.
What would be the best way to do this? The challenge is that the persistence context properties are set in application.properties, and the persistence context isn't initialized unless the Application class is initialized.
I can break out all of these classes into a separate project, and use a different way to define the persistence context there, but this becomes more of a maintenance headache if anything changes with the entities or DAO methods.
What I would really like is to have a way, from the command line, to tell Spring Boot to run another class instead of the main Application (and have the persistence context properly initialized). Any way to do this?
(Note I asked a similar question which got no response: Possible to use Spring Boot repositories from another main class?)
[Edit] is it possible to do this by creating a #component that implements the CommandLineRunner? I just want it to run a simple one-time process and not the full REST application.
There are a number of ways you could do this.
You can have multiple Main classes, and then select which application yuo want to start select main class, however if you don't know how ComponetScan works you will end up loading both applications if you are not careful.
Another way is to use Profiles, you can set the profile when you start your spring app, and then have your web profile that will start Tomcat, and a command line profile that will not .
In the project I'm working on we have choosen to have the data-layer as a completly separate module (same gradle project), which has it's own Spring Context. The data-layer spring context is then used as the parent context for other applications, as a reusable component. It is a somewhat cleaner separations of concerns, were the shared code is clearly marked, instead of having multiple applications inside the same code mudule.

Have one Tomcat application get a bean from another one

Currently I have a Spring project that uses Spring JPA to work with data objects and my database. All of it's functionality can be accessed by calling a single facade bean. I want to make a web application based on this data model, but I don't want to extend this project any further. Instead I would like to separate my persistence and service layers from an actual web application layer. That said, I want to package this project into a ".war" file and deploy it on my Tomcat instance. Upon demand from any other application working on Tomcat I would like to have this other application to be injected with the facade bean from my ".war".
I'm sort of new to Tomcat, and googling doesn't really help me much. So here are problems and questions that I have with this concept:
Is this the right way to do what I want? What I mean is I want behavior provided by my current Spring application to be accessible and reusable by different web applications working on one server. This might be a common case and I would like to know if this is ok as a solution.
If I have this facade bean in XML context or in annotation context of my project, how can I make this bean visible to any other application working on the same Tomcat instance upon being deployed? What should I write in my web applications to have them wired with this bean? If I want this bean to be a singleton and have all calls to it's functionality synchronized, should I do this through my code/context, or can I have Tomcat somehow take care of this for me?
Thanks in advance.
You might want to consider a REST API approach. You can't do "cross application injection" with Spring and JNDI can be cumbersome to use.
Webapps (the things that run in a servlet container like tomcat) are isolated from each other, by design. Sharing may well be a bad idea. However, to share, you can use JNDI. Setting up JNDI in tomcat 7 is described here. You will need a custom resource factory.

New intellij/maven web application, advice on separating modules for service, dao, common libraries etc

So I created a new maven pom based webapp using intelliJ 11.
Now I want to separate out my various layers of the application, so I currently I have:
/myproj
/myproj-common (maven module)
/myproj-services (maven module)
/src/main/webapp (spring mvc application)
So I am using the following:
spring mvc
hibernate
So I will create Dao for each entity, and then a service layer that will use the Dao's and wrap other business logic etc.
How should I setup my maven modules properly without making it too complicated?
Should I create a separate interface module that my other modules will use?
Looking for some practical advice.
I'm using maven to build this also.
I tried this before and moving things into separate modules can't be a little tricky, so looking for some guidance on how to do this.
Update
Should I have a separate module for my entities also?
The simplest way is use only one maven module and do separation on package level.
If you need more I can recomend this setup:
myproj-services - entity classes, service interfaces
myproj-services-impl - implementation dao and services
myproj-ui - your spring mvc classes
Ui depends only on services and services-impl depends only on services.
To reply to your update: IMO yes.
To follow the DDD you should have a model module that contains your entities and DAO's and a service module for for your services.
One step further is splitting up the service module into a service-api module (service interfaces) and and service-lib module (implementations). This also entails then that you don't pass entities from your service module to your web modules by TO's (or views if you prefer).
Another related tip: if you're afraid your service classes will get too big (hence difficult to read/maintain/test) consider splitting them up into Business Objects. So, instead of having a UserService containing all the code you have a UserServiceFacade which delegates to MakeUserBO, FindUserBO, ... . These BO's are responsible for one (or more if related) tasks and can easily be reused by other services or other BO's. BO's are short, to the point and therefore easily to read/maintain. It is also easier to mock specific BO's while you're testing other.

Repackage several WARs into one EAR

I'm working on a project that have several webapps (WARs) built with Maven and deployed in a Java EE.
These WARs share several common business JARS (like one containing domain objects which are loaded from hibernate) and other framework JARs like Spring and Hibernate.
They use Spring MVC, and the Application Context loads Hibernate. As each WAR has its own Classpath in the servlet container, the Hibernate cache (EHcache) is not shared.
What I'd like is to share the cache and also the hibernate session factory bean (as well as other common beans) betweeen the different WARs. I think this is possible by repackaging those WARs inside an EAR and then I'd have to make a spring configuration XML using those commons beans and in the WAR's Spring XML use something like SingletonBeanFactoryLocator from what I've read.
What I'm asking here is if there is a simple way to do this, minimizing changes to the WARs' POMs
Note: I'm familiar with WARs, tomcat and servlets, but not so much with EARs.
Thanks in advance.
Hmmm... Most Java EE containers use isolated classloaders for WARs, even in an EAR (even if the Java EE spec does not mandate class loading isolation among modules of a single EAR) so I wouldn't expect to much from an EAR packaging, especially if you want your application to remain portable (i.e. if you don't want to rely on any app server specific behavior).
Now, if really it makes sense to share your session factory and your 2nd level cache between several applications, maybe consider merging them in a single WAR. That would be the easiest way IMO. But I'd be tempted to ask why are they separate then? When applications are separate, they have most of time separate governance and I don't know if deploying them together would be a good idea in such case.
And if merging the WARs is not an option, please tell us which container you are using.
Have you considered making use of a coherent clustered L2 cache? If you're using multiple app servers you might see more benefit then as they would all be sharing the same coherent cache
Using a shared parent application context in a multi-war spring application
http://blog.springsource.org/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/

Categories

Resources