cancel
Showing results for 
Search instead for 
Did you mean: 

JPA/EJB3: DC reuse

former_member190457
Contributor
0 Kudos

Hi developers,

In my project, I am using an ejb dc with JPA facet enabled.

It now contains both EJBs and entities.

The project has grown big, so I would like to create new EJBs in new DCs.

How can I use in DC 1 the entities/persistence context defined in DC 2?

Thanks, regards

Vincenzo

Accepted Solutions (0)

Answers (1)

Answers (1)

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenco,

I strongly recommend you stay with one DC and a clean package structure. In JPA-theory, you can reference a jar file (e.g. content of DC 1) in persistence xml of DC 2 where the persistence context is defined. But if you want to use JPA Facet and JPA Validator on both DCs, you will get into trouble with the tools - you probably cannot activate JPA Facet in DC 1 without an - unwanted - persistence.xml in it.

Another example: With JPA Facet and SAP JPA as persistence provider, you cannot have a mapped superclass in DC 2 and its extending class in DC 1. DC 1 will not build because the JPA Validator does not find the mapped superclass in DC 2 and you cannot deactivate the validator. Furthermore, the dictionary-tables of DC 1 will not be built at all or not correct.

There are more traps like this. The SAP tooling supports an EJB DC with JPA facet that contains ALL Entities for this persistence context, but no DC-splitting. I also recommend to put all services that work on attached entities (that is with EntityManager) in this DC.

Regards

Rolf

BTW Take a look at the excellent answers from Adrian Goerler in this forum about details and limitations of SAP JPA (e.g. about lazy load, orphan removal).

former_member190457
Contributor
0 Kudos

Hi Rolf,

thanks for answering in such detail, and yes I have checked the answers from Adrian as well, in particular with regard to lazy loading.

The point is in this way JPA cannot be scalable over large projects, unless I use multiple EntityManagers.

I know that the scope of a persistence unit can be a whole ear if the ejb-jar containing the persistence.xml is placed in the EAR/lib directory (i.e. any ejb packed in the ear can use the persistence unit).

I would like to pack the ejb-jar of my persistence unit in ear/lib folder, using SAP tools however, so that I need not pack it manually each time.

Using a Plain java dc I can define an assembly public part, reference it from an ear, declare it as "bundled lib" and it will smoothly be packed inside the EAR/lib folder.

Unfortunately however, the "bundled_lib" option is not enabled when an ear depends upon an ejb dc.

How can I do this?

Thanks, regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo,

what is wrong with multiple EntityManagers? -

"bundled lib" cannot be checked on EJB DCs because it is the only option: EJB DCs are always bundled as jars into the ear, EJB DCs are always "bundled lib"s. And it is better to have the jar in the top-level of the EAR, not in the lib folder (@Entities are not found in the lib-folder). You can reference any EJB jar in persistence.xml (without path) which is packed in top-level of the EAR (this is what happens if an EAR DC has ejbjar-dependency to an EJB DC).

If I understood your initial question right, here is how it works:

DC1: EJB-DC, no JPA-Facet, no persistence.xml

This DC contains an @Entity, let's say Person.java

DC2: EJB-DC, JPA-Facet, persistence.xml

E.g. SLSBs that reference @Entity Person of DC1 are located here. So DC2 has client-dependeny on DC1.

In the persistence.xml you can reference jar of DC1. Its name can be looked up in gen\default\deploy of the EAR-DC, see below, use Navigator-view - form "vendor~nameofdc1.jar":

<persistence-unit name="blabla"">

<jar-file>demo.sap.com~nameofdc1.jar</jar-file>

You cannot reference the class Person of DC1 in persistence.xml of DC2 because JPA-Validator prevents DC2 from building, but the class is found by the container in the jar anyway. (In fact, you could reference the class if you removed the JPA-Facet on DC2.)

DC3: EAR-DC, ejbjar-dependency to DC1 and DC2

Result: You have your persistence context (persistence.xml) and SLSBs in one DC and the entity in another. Of course you can split the entities over more than one EJB-DC and even have some @Entities in DC2, too.

Tradeoff: You cannot use JPA-facet in the DCs with the @Entities because this would give an unwanted persistence.xml. So no JPA Validator, no generation of Dict-Tables. (But I am not sure if this is really a tradeoff )

Maybe you can add JPA Facet temporarily and remove it and persistence.xml later after the dict-Tables or Table-skripts are generated.

HTH

Regards

Rolf

former_member190457
Contributor
0 Kudos

Hi Rolf, thanks for your in-depth answer.

I see your point but I actually would rather not have multiple EMs to keep things simple, if possible.

However I can see the structure you would use to "componentize" EJB development and the tough tradeoffs it requires.

With regard to your other statement:

"bundled lib" cannot be checked on EJB DCs because it is the only option: EJB DCs are always bundled as jars into the ear, EJB DCs are always "bundled lib"s. And it is better to have the jar in the top-level of the EAR, not in the lib folder (@Entities are not found in the lib-folder). You can reference any EJB jar in persistence.xml (without path) which is packed in top-level of the EAR (this is what happens if an EAR DC has ejbjar-dependency to an EJB DC).

I understand that you would like to define a persistence.xml in the META-INF folder of the EAR, and have a simple ejb-jar with the entities in the EAR itself. This must surely work but prevents JPA-facet usage.

The solution I was suggesting is that no persistence.xml be placed in the EAR/Meta-inf folder.

On the contrary, I would place a whole EJB-JAR (with its persistence.xml) in the EAR/lib folder, so that every archive in the EAR can see the persistence unit in the lib folder.

This works in practice and also the specifications says so.

What's so interesting about the bundled_lib option is that it not only "bundles" the referenced public part in the EAR, but it also places it in the EAR/lib folder, not in the EAR root. This way the scope of the persistence unit is the whole EAR, and at the same time the ear has no persistence.xml.

I have tried putting the ejb-jar (only entities and persistence.xml, no ejbs) in the EAR/lib manually and it works.

The advantage of this solution is that the EAR has no persistence.xml and jpa-facet can be freely used where appropriate.

So again: does anyone know how to force the public part of an ejb (ejb-jar) to be placed within the EAR/lib folder?

Thanks again

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo,

I think you misunderstood my suggestion in one point. The persistence.xml is not placed inside the EAR DC, but in one EJB -DC, DC2 in my post. This allows usage of JPA Facet at least in one EJB-DC. But I understand that this is not satisfactory.

If you cannot add an EJB DC as bundled_lib to your EAR DC, why not use an Java DC for the entities and enable it for a JPA Facet?

Create a Java DC and add dependency to SAP's engine.jee.facade to add javax.persistence etc. into the build path. Add your entities in packages and add Public Parts for compilation (for the other EJB DC) and assembly (for the EAR DC). You will notice that "Project Facets" is still not visible in the Project Properties of the Java DC so JPA Facet cannot be added but - here is the trick: In the EAR DC, add dependency to the assembly Public Part of the Java DC. Now "Project Facets" is visible in Project Properties of the Java DC and JPA Facet can be added. This yields an EAR with the Java-DC with entities bundled as jar in the EAR-lib folder.

(The persistence.xml in the JPA-facetted Java DC is required for JPA facet, but not part of the PP and not bundled into the jar.)

Unfortunately, I have to add something like

<jar-file>/lib/demo.sap.comdummyjavapp_assembly.jar</jar-file>

into the persistence.xml of EJB-DC. If you know how you can get rid of it please let me know.

Regards,

Rolf

former_member190457
Contributor
0 Kudos

hi Rolf,

the java DC trick is really outstanding and will try it shortly.

I think that having the persistence.xml exported in the assembly public part would be good however.

Have you ever tried to add also the whole META-INF and persistence.xml of the JPA-enabled Java DC to the assembly public part?

Thanks, Regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo,

I think it is best to have META-INF/persistence.xml in a jar file at top level of the ear, not in the lib folder of the ear. I did not yet manage to inject a persistence unit that is defined in a persistence.xml inside a jar that is in the lib folder.

You can either put persistence.xml in a EJB-DC or create another assembly public part for a Java-DC that is not "bundled_lib" into the ear (and exclude it from the first assemly pp).

But remember: You have to add every Java DC that contains entities as <jar-file> to persistence.xml (see 6.2.1.6 of Java EE persistence spec "ejb-3_0-fr-spec-persistence.pdf") since the class path is NOT scanned for entities, only the "root of the persistence unit", that is the jar the persistence.xml is in.

Regards

Rolf

former_member190457
Contributor
0 Kudos

Hi Rolf,

maybe I can return the favour:

in order to inject a persistence context packed in a jar in the EAR/lib folder,

the jar archive must contain only entities and META-INF, no ejbs.

I don't know why this is, but I managed to have it working.

Please let me know if this works.

I am trying to use the tweaked java-DC with JPA facet.

Thanks, regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo,

thanks, that was exactly the point. With ejbs in the ear root, injection of the entitymanager works fine even if defined in a lib-jar.

ejb-jars belong in the root of the ear, that is probably the reason why they (SAP) do not support "bundled_lib" on ejb-dcs.

What is unsupported is that JPA entities exist without ejbs (even in Java SE) so JPA facet makes sense in every Java DC. This can only be done with the trick mentioned above or - equivalent - manually edit the .project file and some files in the .settings folder (which are local only if you work with NWDI).

Your suggestion to place the entities and persistence.xml in separate jars into the lib folder is a good idea - probably the best way to scale large JPA-projects and stay with one persistenceUnit. This should allow e.g. cross-dc @OneToMany-relations.

Regards

Rolf

former_member190457
Contributor
0 Kudos

Hi Rolf,

The test was successful, an example about JPA componentisation can be as follows:

- Java DC (tipically only 1, as each dc of this kind defines a different persistence unit): this dc contains all @Entities and absolutely no EJBs. Two public parts, one for assembly, one for compilation. JPA Facet must be enabled. In order to have JPA facet selection enabled in NWDS, the EAR dc must depend on the assembly public part of the Java dc. The public parts of this Java DC contain the whole package trees and the meta-inf folder with their respective contents. Persistence.xml is provided along with this DC in the META-INF folder.

- EJB DC (1..n: as many as you want): it contains all the ejbs you develop. It depends upon the compilation public part of Java DC. If the only persistence unit used is the one defined in the Java DC you need not specify anything in the @PersistenceContext annotation in your Ejbs

- EAR DC (1..1): it depends upon the assembly public part of the Java DC ( BUNDLED_LIB option specified ) and also on the EJB DCs. The EAR archive structure must be as follows: the java dc assembly public part in the EAR/lib and the ejb-jars in the EAR root. In this way the persistence unit defined in the Java DC is visible to all the EJBs in the EAR.

The advantage is that you can clearly isolate Business Logic Layer (EJBs) from Persistence Layer (JPA entities).

In addition, when using version control systems, you can increase the degree of concurrent modifications, provided you have consistently arranged your EJB DCs.

I invite everyone reading this to provide feedback or comment, as this is a fundamental and critical issue.

Thanks, regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo

thank you for the excellent elaboration. Another advantage is that putting the entites in the lib-folder ensures that the application class loader loads them and they are visible to the entity manager without any potential issues.

If projects grow bigger, you may want to split the entities into more than one DC:

Instead of 1. (one Java DC) you may have many entity-Java DCs that share a single persistence unit (that is defined in an additional Java DC, see below).

In each entity-Java DC you can activate JPA facet as you describe, but NOT publish the persistence.xml-file in assembly public part (e.g. exlude it in the META-INF folder). The persistence.xml in an entity-Java DC exists only for design time to satisfy JPA Facet and JPA Validator. The persitence unit should be named "unused" or so.

The "real" runtime META-INF/persistence.xml that defines the common persistence unit can be put in a seperate Java DC. This DC has only an assembly public part with persistence.xml. This DC has no JPA facet at all and persistence.xml is edited manually. This allows each persistent <class> of the entity-Java-DCs mentioned above to be listed in the persistence.xml. As an alternative, the persistence.xml can reference the jars of the assembly public parts of the entity-Java-DCs with the <jar-file> element, in this case you could even add a JPA Facet and have a bit more comfort with persistence.xml-editor.

The rest - EJB DCs and EAR which bundles all entity-ava-DCs and the persistence.xml-Java DC with bundled_lib option - as in your post.

This allows modularization of the entities in different DCs.

(Across entity-Java-DCs, you may have inheritance of entities or even unidirectional xToOne relations, but this may require to turn off the JPA Facet because the SAP JPA Validator does not support it and cannot be deactivated.)

Regards

Rolf

former_member190457
Contributor
0 Kudos

For those interested, I have published a blog with the findings we have made, [here|http://www.sdn.sap.com/irj/scn/weblogs?blog=/pub/wlg/19601] [original link is broken] [original link is broken] [original link is broken];.

Regards, Vincenzo

todor_petrov
Contributor
0 Kudos

Hi,

as I also posted a reply to the blog. I would like to bring your attention to a strange problem that comes up when the META-INF folder is added to the Assembly part of the JPA DC.

When ran, the application crashes with a ZIP Exception, which is very strange and does not bring any useful information. If you want to see the exact log, please click on the link in the post before and read the comments.

Help is appreciated.

BR,

Todor

former_member190457
Contributor
0 Kudos

Hi Todor,

first things which come to mind:

- on SDN and SAP Notes there are several circumstances which can cause ZipException (permissions etc)

- did you specify "bundled_lib" as dependency option?

- what is the structure of the EAR file? The entities and meta-inf folder should be packed in the lib folder

- Is everything ok if you remove just the meta-inf folder from assembly pp?

- Which release are you on? I tested this procedure on 711 SP4

Regards

Vincenzo

todor_petrov
Contributor
0 Kudos

Hi Vincenzo,

- I checked the ZIP exceptions on SDN, but nothing is really like my case.

- yes the bundled_lib option was specified - here I am not sure should I also specifiy that the reference should go in the LIB folder, which can be checked in the properties of the project under JEE Modules references.

- If I don't include the META-INF folder the ZIP exception is gone, but the J2EE doesn't lwork. Is it a problem if I also generate web services from the EJBs that are referencing the JPA project?

- I am on realease 7.2 SP3

Thanks for getting in touch so fast.

BR,

Todor

former_member190457
Contributor
0 Kudos

Hi, I would definitely try to remove the web services

JAX-WS can pull some strange tricks when non-serializable classes, for instance, are exposed in WS interface.

Let me know the outcome

br

Vincenzo

todor_petrov
Contributor
0 Kudos

Hi,

well unfortunately we need those WS.

Where do you suggest to introduce them?

BR,

Todor

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

you do not need to touch the properties in the Java EE Module Dependencies or Project References on the project properties of the EAR-project. This is done automatically by checking "bundled_lib". It is even not a good idea to edit this options since you may unintentionally remove DC-dependencies by doing so...

As mentioned above, the 7.20 SP3 is in trouble with persistence.xml bundled in the lib folder. If possible, create a DC that contains only META-INF/persistence.xml (and remove it from the DC it is contained now), create a Java Package Archive Public Part on META-INF and bundle this persistence.xml-PP into the EAR without bundled_lib.

Cheers

Rolf

todor_petrov
Contributor
0 Kudos

Hi Rolf,

very good hint. However can you please provide how exactly should the persistence.xml look like then, because we are having problems referencing the entities from the Java JPA DC.

BR,

Todor

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

you will have to remove the JPA Facet from your JPA Java DC. You may think this is a restriction, but you can live very well with it. The JPA Facet in Eclipse 3.4 does not support persistence.xml in another project than the entities (due to a quite complex eclpse dali tools bug solved in a later release in eclipse, 3.5 if I record it right). (see entry #4 in this thread)

At development time the persistence.xml is not referenced at all without JPA facet.

Cheers

Rolf

todor_petrov
Contributor
0 Kudos

Hi Rolf,

you got me confused here. In your previous post, you are saying that we should move the persistence.xml in a separate DC and in your last post, you say that it cannot exist without the JPAs in the same project.

Could you please provide me with the full picture on how to arrange the files so that I have the JPAs, the facades and other EJBs in separate DCs?

BR,

Todor

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

- one Java DC with all of your @Entities, dependent on engine.jee5.facade to resolce the JPA annotations, but without META-INF/persistence.xml and without JPA facet turned on --> bundled "bundled_lib" into the EAR.

- one Java DC with only META-INF/persistence.xml (without JPA facet, too) --> bundled without bundled_lib into the EAR.

Cheers

Rolf

todor_petrov
Contributor
0 Kudos

Hi Rolf,

OK, now its clearer in any case. Just what is missing is, how are both Java DCs referenced in the EJB, where the JPA Facets are enabled?

BR,

Todor

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

the DC with the @Entities is referenced by the EJB DC via compilation PP.

There is no need for a reference from the EJB DC to the DC with the persistence.xml. The DC with the persistence.xml is referenced only by the EAR for deployment since it is not needed at all during compilation time.

And there is no need for a JPA facet on the EJB DC.

Cheers

Rolf

todor_petrov
Contributor
0 Kudos

Hi Rolf,

OK, last question. No JPA Facet on any of the projects means that we cannot generate the Tables diagram, correct?

I am asking, because this was one of the features that helped a lot, when you wanted to get an overview of how your model looks like.

BR,

Todor

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

this is correct, but you may try the following (untested):

Leave the JPA Facet turned on in the @Entities DC.

Switch the JPA Platform from SAP JPA to Generic or EclipseLink in the project properties, entry JPA.

Deactivate the JPA Validator in the Validation preferences (either in Workspace preferences or in the project properties).

Hope that diagrams will still work without persistence.xml

You need to switch away from SAP JPA because SAP JPA ignores the Validation preferences so with SAP JPA, you cannot get your project valid without a persistence.xml in the same DC.

Cheers

Rolf

todor_petrov
Contributor
0 Kudos

Hi Rolf,

I see. That summarizes everything so far.

In my humble opinion splitting the JPA from EJB is not worth the hassle with all those restrictions and limitations.

I guess it would be better to give some of those ideas commented here to SAP Developers, who should optimize the JPA perspective to be productive and user-friendly and not restricted and limiting.

Anyway just my opinion as I said.

I would like to give you the credit for your answer since it was so complete and helpful, but unfortunately this thread is closed.

Maybe sometime when I am in Germany, we can grab a beer and see how things evolved since that forum message:)

Thanks again for the professional response.

BR,

Todor

former_member190457
Contributor
0 Kudos

Again thanks Rolf for your help.

You might want to post an update to my blog (or post a blog on your own ) on JPA in CE 7.2.

Hope to get my hands on 72 asap

Thanks, regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Todor,

I appreciate your imagined beer more than points

It is a pleasure to know there are others "outside" that use the SAP NetWeaver Java as what it is - a great Java EE Applicatoin Server and to discuss with you. Since SAP announced Windows 64bit support for NWDS by the end of 2010 and the current Eclipse Helios (3.6) is the first Eclipse with Windows 64bit, I hope that SAP will upgrade from Eclipse 3.4 to 3.6, and some JPA / Dali restrictions could be solved.

It is comprehensible that you hasitate to abandon the support from diagram editors for entities etc., but you are rewarded by a clean architecture as Vincenzo points out in his great blog. So the larger your application grows, the more the gain of DC-separation and the lesser the advantage of this tools. E.g. Java SE JUnit tests are cleaner with a JPA DC that is not mixed up with EJB stuff.

(JPA IS already a Domain Specific Language for relational persistence, why need another DSL on top of it? And very soon you will simply know the @Entity and @ManyToOne @Annotations).

But it depends on the scale of your project and can be done later in the run of the project. After starting with a clean package structure in one DC that separates Entities and Java SE classes from EJB classes, you can split into more DCs later. Splitting one DC into two DCs is easier than to merge two DCs into one.

Cheers and skoal

Rolf

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo

thanks for your encouragement, I will think about it - there is too few Java EE stuff like your blog in SDN.

Regards

Rolf