I am developing a JavaEE application and I use JPA/Hibernate as a persistence engine. While developing the application, some questions raised to my mind.
The application consists of users and their roles in a N:M relationship. Here is the database subset of the above tables.
I am relatively new to Hibernate and at first I asked IntelliJ IDEA to generate the mapping for me. What it did was generate the following Java classes:
UserEntity.java
RoleEntity.java
UserXRoleEntity.java
UserXRoleEntityPK.java
Thus, it generated a mapping for the relation table and two 1:N relationships, one between user and userXrole and one between role and userXrole.
After some research, I found that, by using the #ManyToMany annotation, I could omit mapping the userXrole table into a Java class and just declare it within the annotation as the #JoinTable.
So the question is:
Why does IntelliJ generate the entities that way?
Is it just a more generic way that helps generation, or does it have any other advantages. Would you argue in favour of one way or the other?
Is it just a more generic way that helps generation, or does it have any other advantages.
JPA doesn't know if a table is just a join table, that's why you have to tell it (using #JoinTable). The generator might guess, but it will probably only generate #ManyToMany if your table names match JPAs defaults.
Would you argue in favour of one way or the other?
I'd use #ManyToMany if i don't have a reason (finer grained control over lazy/eager fetching maybe?) for separate mapping entities, mostly because less code = less errors.
Related
This can seem a stupid questions for some people, but I couldn't find any information anywhere why we should use mappings (#OneToOne, #OneToMany etc) in JPA while defining entity classes. I know one the advantage is code reduction, so that we don't have to explicitly write queries in order to fetch data from relationship tables. But is there any other benefit (from code optimisation perspective at SQL side) that we have?
The reason is to load object trees or graphs.
That's the goal of object-relational mapping to fill the gap between database tables and objects.
And as you said it reduces code.
In a summary the idea of the ORM is to map tables to objects, so the developer works with the objects instead of the tables.
Tables in SQL have relationships through key columns.
in JPA these relationships are expressed via #OneToMany, #OneToOne etc.
This means that if you want to fetch a row from one table and join that with corresponding row from another table (via a relationship) the JPA implementation (mostly Hibernate) can do that for you, looking at the relationships you have defined for your entities.
You need to describe the entities relationships because it's part of the DB schema model which you are mapping to application level objects. As you mention - it saves you writing the SQL queries yourself, but that's not the main point.
The main point is that you can model/represent one domain (database tables, rows, relationships, SQL commands) as another type of domain (objects/classes, OOP paradigm, programming language commands) which completely shifts the way you work with it.
Let's assume that we have java entities already implemented and annotated with Jpa annotations.
We also have an existing database slightly different to the schema described by said entities.
How I can link the data base with my entities without the code?
Otherwise, how can i proceed from the begining when implementing my entities to make this stuff configurable ( give the user the possiblity of specifying the names of the columns corresponding to the fields of each entity in an externalized configuration file)?
NB: I use hibernate as an ORM.
I believe this is what you are looking for
It istrong texts possible to easily generate random entity using hibernate.
For example, I have got a simple entity User with 2 fields (name and surname) and I need to create 100 different entities.
Is it possible using Hibernate to create different entities with random fields? And when I have a table Phones with relation ManyToOne with User can I also create 10 different random phones?
Does Hibernate have a class or function to do this?
This is not a problem that Hibernate has attempted to solve since it is an ORM.
This is an entirely different problem and for the simple case you describe should be fairly easy to do yourself.
However, when you start talking lots of tables and validation etc. this is not a very easy problem at all.
You should look at Hibernate as a translator between Object world and Relational world. It doesn't want to manipulate objects, create new objects and so on. Its only task is to ease life of programmers while coding in OO and persisting in Relational. So short answer is NO, it hasn't been built for this purpose.
In our project we have a constraint of not having the luxury to alter the table structure already in place. The tables are highly denormalized in nature.
We have come up with good POJOs for the application. We have the Entity beans generated out of the exiting tables. Now we have to map the POJOs to the entities so that we can persist.
Ultimately, we combine a good POJO with a bad table. Any thoughts on options/alternatives/suggestions to this approach?
Hibernate/JPA(2) has a rich set of functionality to manipulate the mapping (so that your objects can differ from the tables), so that many (NOT ALL) old tables can be mapped to normal object. -- May you should have a look at this first, any use your pojo/table-"solution" only if this mapping is not powerful enough.
If you have a read only application, you can think of using views to make your table/views more like you objects. This may reduse the amount of strange mapping.
I don't know your mapping, size of the application or use case, but have you considered not to use Hibernate? I ask this, because I can imagine (how I said: I don't know you application), that in a architecture like this, no Hibernate feature is used and so Hibernate will add only a not needed complexity.
If you are using Hibernate you should be able to map your POJOs to the table structure using only XML files, without creating new Java beans. This would allow you to easily change the mapping if all of a sudden you can change the tables structures and make the economy of intermediary beans. That's the best you can do.
There's an enterprise application using Java + Hibernate + PostgreSQL. Hibernate is configured via annotations in the Java source code. So far the database schema is fixed, but I faced the problem that it needs to be dynamic:I can receive data from different locations and I have to store these in different tables. This means that I have to create tables run-time.
Fortunately, it seems that all of these data coming from the different institutes can have the same schema. But I still don't know how to do that using Hibernate. There are two main problems:
How to tell to Hibernate that many different tables have the same structure? For example the "Patient" class can be mapped to not just the "patient" table, but the "patient_mayo_clinic" table, "patient_northwestern" table, etc. I can feel that this causes ambiguity: how Hibernate knows which table to access when I do operations on the Patient class? It can be any (but only one) of the former listed tables.
How can I dynamically create tables with Hibernate and bind a class to them?
Response to suggestions:
Thanks for all of the suggestions. So far all of the answers discouraged the dynamic creation of tables. I'll mark Axel's answer, since it achieves certain goals, and it is a supported solution. More specifically it's called multi-tenancy. Sometimes it's important to know some important phrases which describes our problem (or part of our problem).
Here are some links about multi-tenancy:
Multi-tenancy in Hibernate
Hibernate Chapter 16. Multi-tenancy
Multi-tenancy Design
EclipseLink JPA multi-tenancy
In real world scenario multi-tenancy also involves the area of isolating the sets of data from each other (also in terms of access and authorization by different credentials) once they are shoved into one table.
You can't do this with Hibernate.
Why not extend your patient table with an institute column?
This way you'll be able to differentiate, without running into mapping issues.
I am afraid you can't do this easily in Hibernate. You would have to generate the Java source, compile it, add it to your classpath and load it dynamically with java.reflection package. If that works, which I doubt it, it will be an ugly solution (IMHO).
Have you consider using a schema less database i.e: NoSQL databases or RDF
databases. They are much more flexible in terms of what you can store in them , basically things are not tight up against a relational schema.
In most environments it is not a good idea to create tables dynamically simply because dbas will not give you the rights to create tables in production.
Axel's answer may be right for you. Also look into Inheritance Mapping for Hibernate.
I agree that its not advisable to create tables dynamically nevertheless it's doable.
Personally i would do as Axel Fontaine proposed but if dynamic tables is a must-have for you I would consider using Partitioning.
PostgreSQL allows you to create ona main table and few child tables (partitions), records are disjunctive between child tables, but every record from any child table is visible in parent table. This means that you can insert rows into any child table you want using just simple insert statement (its not cool but has the same level of complexity as composing and persisting an entity, so its acceptable in your case) and query database using HQL