Separating JPA information from POJO - java

I am working on a project that will have entities persisted to a database using JPA. We will be using Maven as the project management framework. I am wondering if it would be possible to create one project for the POJOs and another for the persistence definitions and then "combine" the two into a single output that contains the POJOs and their persistence information.
Basically I am trying to separate the code that POJOs from the persistence definition. Because the POJOs may be reused by several different projects that may or may not need to persist them and may or may not want to change the persistence information. (Similar but not quite the same as Is it possible to build a JPA entity by extending a POJO?)
I have two ideas on how I might be able to do it. If I were to use the POJOs in a web application I could provide persistence.xml and map the classes in that project and just add a dependency to the project containing the POJOs. But if I wanted to create a single jar file containing the persistence information and the POJOs, I think I could use the shade plugin?
Is there any other way to essentially merge two maven projects into a single output and is this a reasonable thing to want to do?

If I remember correctly, then annotations do not have to be on the classpath if you're not using them. The annotated classes can still be loaded.
So my recommendation would be:
Stick with the JPA annotations, as this is the easiest way to define the mappings and tooling support is usually better.
Declare the JPA dependencies as optional and probably also as provided.
If you need to override the mappings defined by the annotations, it should be possible to do this using the persistence.xml, AFAIK (never tried).

I do appreciate the input. In the end, the solution for me was to create two projects. The first provided the definition of the POJOs without any JPA information. Yes there are some JPA related members such as id but I will address those. The second project contained the JPA metadata (orm and persistence XML files).
As for the members related to persistence (e.g. id) I could probably live with those in the model classes but using the suggestion in this post (Is it possible to build a JPA entity by extending a POJO?) I extended my POJO classes and declared id in the "entity" sub classes. This does require some consideration when defining the POJO in terms of access to members.
One thing to note, this solution runs into trouble when you have a class hierarchy (inheritance in your model). The classes in your "pure" model inherit from some common class. That class is then extended in the "persistence" model to provide the id and other persistence related members. Now if the persistent subclasses inherit from the classes in the "pure" model, they do not inherit the id and other persistent members.
There may be workarounds in different inheritance mapping such as table per concrete class.

Related

How to separate class declaration from its database relation definition

Context
I have a case in a kotlin project, where I generate classes using protocol buffers.
I'd like to create for those classes mapping definitions, so I could store them in db.
However, because protobuf classes are generated,
I cannot add Entity annotations to them.
Therefore I am looking a way to annotate those classes outside of their definitions.
What I tried
I was reading documentation for hibernate,
as I remembered it could create mapping definitions separated from class declarations:
Hibernate in 3.3 had an option to create xml mapping definitions:
https://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html
However, it seems missing from newer documentation and in 5.6 the closest I saw was:
https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#dynamic-model
Questions
Is it possible to still use XML mapping definitions in hibernate?
Why XML approach was removed from the Hibernate documentation?
OR
Are there any other solutions that would allow me to store protobuf objects in database without using hibernate?

How do I instantiate an EntityManagerFactory that augments a persistence.xml with extra classes?

I have a module with a persistence.xml for several classes. I have an application which uses that module, but wants to augment that EntityManagerFactory with a couple of other classes that are specific to this application and don't belong in the module.
If I create a persistence.xml in the application that overrides the persistence unit it does not work reliably (it does work when run from IntelliJ's debugger, but does not work when invoked using a maven appassemble package) because it seems the rules governing which of the persistence.xml files in the various jars takes effect are beyond my understanding, and probably difficult to control.
If I create a second persistence unit to contain only the new tables, then I will need multiple EntityManagerFactory-s to retrieve the various object types in JPA. I do not currently need to execute queries that join objects from the library module with objects specific to the application module, but I am reasonably certain it would be impossible if the objects were in different persistence units.
Even worse, using multiple persistence units appears to make derby angry because the second persistence unit fails when it finds that the database is already opened (by the first persistence unit; why derby can't share in the same JVM I don't know, and there may be workarounds I do not know).
What are the dangers if you have persistence units that overlap? ( both units have objects mapped to the same table in the same database )
What are the proper guidelines for dealing with persistence units from multiple .jars ?
Using standard JPA functionality, there is no means to supply additional entity classes in runtime.
The approach I recommend is to remove persistence.xml from your modules and create orm files, which contain the same entities as original persistence.xml files.
Then create single persistence unit in the application and include orm files from all required modules.
This is what has always worked for me an it seems the only reasonable approach with current JPA version.
This way, you end up with single persistence unit, and still having modular and extensible sets of entities.

Over exposure of hibernate pojo

Well I have recently started reading up on Hibernate so my knowledge is very raw.
I read somewhere that you should not expose your hibernate pojo classes directly on your application rather you should create classes which represents Pojo classes on your application. It's like custom classes which use only some or all of the fields of the Pojo classes.
Can someone put some light onto this as to how in an application we can stop the over exposure of Pojos or what is the correct way of using Pojos and custom classes which are returned from the server.
Better you right your own POJOs classes with required fields... And also write translators to translate data from hibernate POJOS to you Pojos.
Note:- If you are evaluating Hibernate for something, have a look on JOOQ.....
Tomorrow is a world with out ORMss........
http://www.jooq.org/doc/3.6/manual-single-page/
In general, I'd say it depends on your needs, but if you want to do it right, I suggest you have create custom classes for your DTOs that contain just the information you need. I have written an article about why using entities might lead to problems and how you can implement DTOs with Blaze-Persistence Entity Views to solve your problems. That might help you a bit to understand the implications.

Design pattern for modular application (how to reuse entities)

I have the following scenario:
A JAX-RS Webservice that is responsable for the business logic and database interactions.
A webapp that will be used by the end users.
A webapp that will be used by administrators.
My problem is that I want to reuse the entities from the webservice on the other apps, but it is highly wrapped with frameworks like JPA, JAX-RS, CDI, among others... So I am having a hard time to isolate them. What I want is to know the best workaround and why should I use it instead of others.
Maybe DTO is the way to go (with support from some object mapper library like Dozer)
Please take a look at following article for more details: http://zezutom.blogspot.com/2012/02/thoughts-on-data-transfer-objects.html
Write you entity objects as Plain Old Java Objects (POJOs), with proper constructors, setters, etc. Apply the annotations that allow the JPA to persist them and do the object to relational mapping in such a way that, if those annotations were all stripped away you could still create and manipulate those objects fully, using the public methods of the class. It can be helpful if you create the POJO first, then add the annotations afterwards.
As the POJOs stand alone they are not at all part of your repository layer. You can use them without using the JPA at all.

Where should we place HBM files?

We have a team of 5 to 8 people and our project is using Hibernate (ORM) but we are facing some problems related to HBM files and there respective VOs (Value Objects). Actually we all are working on different modules and we all are creating HBM files and there respective VOs as per our module (so we have our HBM files and VOs specific to our module). If common table is used in more than one module then we have multiple HBM file and their VOs for that single table. So should we place all the HBM files anf VOs to a specific location or keep them module specific even if we have multiple HBMs and VOs. Please suggest the GOOD or BAD practice as well.
Thanks
From the query it seems each module has its own data access. If its not very complex, you can put all the data access in separate module. A project can have multiple modules but should have one place for data access.
As suggested, you can have a DAO module which is only doing to Data related operations.
Packages can be used to identify different DAO types.
The common DAO should be kept simple. Business Logic should not go in that. Logic should be handled at a higher level.
Other than that :-
Your project should be properly structured i.e. packages should be clearly defined.
module1/src/../com/../../bl
module2/src/../com/../../b0
dataacess/src/../com/../../bl
dataacess/src/../com/../../bo
Dependencies should be clearly extrapolated. If you have one DAO module then DAO should be independent. Other Modules should depend on DAO. If its java you can use maven to do this.
Finally its the choice we make. There will be lot of best practices. You should choose what suits best in your scenario. In the end it should be simple and manageable in future.
There should be a common project that will contain all DAO related stuff. Each module/project will include that commonDAO project in its classpath to perform hibernate and database related operations. This will overcome HBM files duplicacy and ease to maintain code.

Categories