we've a persistence archive containing only Entities and the persistence.xml. And we've an ejb module containing the ejb stuff.
Now for a specific use case we need to add an EntityListener which has access to some EJBs in the service layer.
The ejb module depends on the persistence module. However to declare the listener in the Entity the persistence module needs to know about the class in the ejb module. A cyclic dependency is not possible and having a third module containing only the JPA listener leads to cyclic dependencies as well.
So the only option I see is to merge the ejb module and the persistence archive into a single module. However that way we loose the flexibility to use the persistence archive in another application to connect to the remote interfaces without carrying the whole ejb jar's content.
Any ideas on how to solve this and stay modular (separate ejb and persistence modules?).
We're talking about a JEE7 application.
You could move the persistence.xml from your JPA project to your EJB project and then use the <jar-file>packedEntity.jar</jar-file> XML element. Check this answer.
One idea is to use your Source-Control-Management (git/svn/cvs) to import the entity package in your EJB project (+the persistence.xml file). This way, you have more flexibility on what/how you define them.
In SVN you have svn:externals. For git check out this answer.
Related
The situation is as follows.
I have a microservice that imports a module. I want that module to be reusable by other microservices and to have it's own data source.
I managed to do this by manually configuring the data source in the module (in a #Config glass), but if I want to import the module, I also have to manually configure my data source in each micro service and specify that it's the primary one.
Is there any way to only configure the module's data base and to let spring do it's automatic config inside the microservices? Thanks, any help is appreaciated.
EDIT: I figured the first part of my question out myself - to avoid closing my question and opening a new one for the second part, i recycle this question and provide the link for accessing remote EJB ont he same applicationserver:
github example, thanks to PiotrNowicki
I have a War and a ear.
The Ear contains a #Stateful EJB, using a PersistenceContext.EXTENDED for some databaseoperations. This Context is extended for access to Lazy-fetched lists in Entities outside the Persistence-bean.
The WAR has a JAX-RS REST-Interface, implemented using #Stateless Sessionbeans, which also do simple operations on other datasources. they do not require an extended context, so they use regular CMT.
the Beans in the WAR however need to call the EAR'S EJBs.
If I just Merge the Projects into one EAR and inject the beans via #EJB, the CMT cannot interact with the Extended Persistence-Context. This is expected, see JPA spec 7.6.3. (#Stateless beans attach a regular PersistenceContext to the transaction, which an extended context does not accept)
So I split the two Services and now need a Service-Interface for interaction.
My Question is:
1) Would remote EJB-calls SOLVE the Transaction-Problem, or would the JBOSS behave like the Bean was Local and try to add the Extended persistencecontext to the local transaction - resulting in the same problem?
My apologies for lengthy question.
I'm working on a EJB application. I have two EJB eclipse projects(Ejb1 and Ejb2) and other dynamic web application(Web1) which will be compiled and added to a parent EjbEar project and packaged as EjbEar.ear file.
Question1: I've first created a persistence.xml in EJb1 project's META-INF folder and this helps me inject the entitymanager into the session beans and start working. (code below)
#PersistenceContext(unitName = "ejbPersistanceunit")
private EntityManager em;
In Ejb2 I've created another session bean and injected the entitymanager same like above(here I did not configure the persistence.xml) but when I invoke from the client, I get the response from both the Ejb1 and Ejb2 projects.
Why does the EntityManger get shared between two ejbprojects? If my Ejb2 project needs another persistence.xml for a different data source, do I create another one or have it included in the existing persistence.xml? will it also be shared ? Does my Web1 project also get hold of the Entitymanager in the same way?
Question2: I have sessionbeans in Ejb1 project and their remote interfaces are created in Web1 project but what is the best approach in exposing these newly created Entities/Interfaces in an ejb project? (For more than one Ejb project in an Enterprise application)
Question3: Ejb 3.0 no longer have the home and remote interfaces correct?
Why does the EntityManger get shared between two ejbprojects?
You can disable this sharing by isoloting Ejb jars if you don't want. If jboss open jboss-deployment-structure.xml and setting the property ear-subdeployments-isolated to true
If my Ejb2 project needs another persistence.xml for a different data
source, do I create another one or have it included in the existing
persistence.xml? will it also be shared ?
It purely depends on your use case,
if you have multiple datasources in your system then I would define my persistence.xml based
the way I package my beans accessing the Persistence Unit.
In case, if all of the entities belonging to both of the datasources are packaged together then I would define 2 persistence Unit in the same persistence.xml
if they are packaged in differently in 2 jars, then any of the following is a possibility
if beans accessing the entities serviced by the same
persistenceUnit/Datasource are packaged together then I would create
2 persistence.xml with associated PersistenceUnit in 2 jars
if isolation is set to false, then I can define my persistence.xml like
above or I would define 2 persistenceUnit together in a single
persistence.xml and would make sure that the jar with
Persistence.xml is deployed first
Does my Web1 project also get hold of the Entitymanager in the same
way?
Yes, you can get access to persistenceContext
Note: I assumed your app server to be JBoss
I have sessionbeans in Ejb1 project and their remote interfaces are
created in Web1 project but what is the best approach in exposing
these newly created Entities/Interfaces in an ejb project? (For more
than one Ejb project in an Enterprise application)
As far as my knowledge goes, it depends on your system Architecture/ Design. If I were you, I would have packaged my remote interfaces and Beans together in the same EJB-Jar and I would either use Business Delegate that lookup the EJB beans or as Remote interfaces are visible in the web, I would inject the same in the web layer and use it.
Ejb 3.0 no longer have the home and remote interfaces correct?
There are no interface called home & remote but the concept is still there in the form of annotations #Remote & #Local, which means you define your interfaces and you can declare either #Remote or #Local either at the interface level or at the Bean level.
I am using Hibernate 4.3.6.Final with JPA and Spring 4.0.6.RELEASE in my project with Java Configuration.
I have two jar files. module1.jar and module2.jar. module1.jar has some entities
and module2 has some entities. I can't use the module1.jar entity in module2.jar without using
persistent.xml and
<jar-file>module1.jar</jar-file>
Is it necessary to have persistent.xml as I am using
entityManagerFactoryBean.setPackagesToScan("com.mydomain") to scan all the entities from all jar files.
No, it is not necessary to use the persistence.xml if you are configuring Spring's entityManagerFactoryBean with setPackagesToScan().
From New Features and Enhancements in Spring 3.1:
3.1.12 JPA EntityManagerFactory bootstrapping without persistence.xml
In standard JPA, persistence units get defined through META-INF/persistence.xml files in specific jar files which will in turn get searched for #Entity classes. In many cases, persistence.xml does not contain more than a unit name and relies on defaults and/or external setup for all other concerns (such as the DataSource to use, etc). For that reason, Spring 3.1 provides an alternative: LocalContainerEntityManagerFactoryBean accepts a 'packagesToScan' property, specifying base packages to scan for #Entity classes. This is analogous to AnnotationSessionFactoryBean's property of the same name for native Hibernate setup, and also to Spring's component-scan feature for regular Spring beans. Effectively, this allows for XML-free JPA setup at the mere expense of specifying a base package for entity scanning: a particularly fine match for Spring applications which rely on component scanning for Spring beans as well, possibly even bootstrapped using a code-based Servlet 3.0 initializer.
I have a big application which i want to break up into manageable modules. I am using spring with Jpa (Hibernate as a provider). I came up with a structure where I have a core module containing all the entity and dao classes, and the other modules make use of the core module regarding persistence, and each one of them will have its own set of service classes and controllers.
All Jpa and spring configuration files are in the core module. With this setup I am facing a problem of autowiring dao beans in the modules making use of the core module. So my question is, is it possible to autowire beans from the core module in the other modules (or probably use a context across modules)? I am also open to suggestions regarding the structure, if there is a better way of doing it.
Thanks
The Core Module must be the parent Spring context that must be setted in each child context module. By this way there's no ploblem with autowiring
Every child context can reach all beans from parent, but be aware of that parent can't see the children
Depending on how you've configured your application, you can do this in several ways, i. e.
Distributing your core module in a separate jar to every module, as it's described in this article Sharing a spring context across multiple Webapps
Programatically, having your core spring xml in each child module, you can do this:
ClassPathXmlApplicationContext parentAppContext = new ClassPathXmlApplicationContext();
parentAppContext.setConfigLocation("spring-core.xml"); // this is your core spring xml
parentAppContext.refresh();
ClassPathXmlApplicationContext moduleAppContext = new ClassPathXmlApplicationContext();
moduleAppContext.setConfigLocation("others.xml");
moduleAppContext.setParent(parentAppContext);
moduleAppContext.refresh();