I have one #Table domain and want to create multiple tables using that. How can I do it with JPARepository.
#Table
public class structure implements Serializable{
...
}
I want to create a lot of tables with different names and same structure in run time and save records to them.
How can I do this with JPARepository?
Creating JPA mapped classes dynamically is not possible. But there are possibles to minimize the code you have to write.
MappedSuperClass
Create one class annotated with MappedSuperclass and let all other classes inherit from it. This way the actual mapped classes contain very little code.
Inheritance
You mentioned in the comments that your classes are different types. This suggests that maybe inheritance with a table per class is the correct way to go.
Again create a superclass with all your proper classes to inherit from, but this time annotate them as with #Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
Partitioning
You write in the comments
Because I'm working on a large amount of data and if I insert all of them in one table my query performance is low.
Which makes me think you might be approaching this on the wrong level and you should really look into partitioning. The availability of this and how it exactly works depends on the database you use. Therefore I just leave a link to Wikipedia.
Related
I'm currently working on improving some old uni assignments moving them from serializable files to any other form of storage, mainly SQL Databases.
I understand the concept of relational database design and the similarities with OOP Classes, however, I'm not entirely sure how to approach this issue from an OOP design perspective.
Right now I have a Hotel class with a List of Rooms as property, each Room has a list of Guests as property (full code here)
Back when using files I could mark these classes with the Serializable interface and store the parent object in a single file. But when using relational DB, I store each list as a single table and use separate queries to obtain the corresponding results. Same goes for the add() operation: with databases, I can do something like Guest.add() and add all the required fields directly to the database, whereas with my current design I need to call Room.getGuestList().add() (or a similar approach).
I totally understand that neither of both approaches is ideal, as both classes should be only worried about storing the data and not about the implementation of an add method, but even if I separate this in a single class, shall I still define a List property within each class?
I'm pretty sure I'm missing a design pattern here, but I cannot find the one that would solve this problem or maybe it's just that I've been taught wrong.
Thanks for your answers
Edit: I've decided thanks to the answers provided to transform my implementation following the DAO pattern as explained in this question and the Oracle documentation.
Normally you would have 3 tables: hotels, rooms, guests.
Rooms would have relation to hotel (hotel id) and guest would have relation to room(room id). That's it.
Those relations can be easily reflected in OOP using some sort of ORM. JPA with Hibernate is an excellent example. Check that out. You will be able to get hotel, its rooms and all guests of hotel just like you described without using a single SQL query in your code.
I have a Database that contains multiple tables which are generated on a per month basis. e.g
Transaction_01_2014
Transaction_02_2014
Transaction_03_2014
.
.
.
Transaction_12_2014
All the tables have the same structure. The only difference is the month and year appended at the end.
Is it possible to map all these tables to a single #Entity class "Transaction" in Hibernate? if yes, do I need to change some configurations? If its not possible this way, how should I operate on these tables in an subtle and simple manner, from my java application?
Cheers!
Yes. You can map multiple tables to a single #Entity class using #MappedSuperclass annotation. By creating a super with this annotation & inheriting it's feature to all sub-classes with different tables in #Table annotation. But, in this case problem of normalization arises.
OR
You can use #SecondaryTable annotation which allows you to specify one or more secondary tables indicating that the data for the entity class is stored across multiple tables.
For more information :
#MappedSuperclass - Java Doc Example
#SecondaryTable - Java Doc Example
Tutorial - Map One POJO To Multiple Tables
If the purpose of this new entity is to read and not for insert, update and delete, like reporting and monitoring then following the approach may help you:
You may create a database VIEW that unions-all these tables.
Having the new #Entity class mapped to these VIEW will solve the problem.
The View's definition(DDL) needs to be updated by a database job
(side by side of tables generation per month )
What is the accepted practice to use multiple database 'models' in a Spring / Hibernate combo ?
Would appreciate some help on an issue that has me scratching my head, as I am no expert in Spring/Hibernate !
We are developing a web project that up until now has been built to the specification of its first customer. All the database tables are mapped to POJOs and we use Hibernate Annotations. Very simply, the project is a CRUD application that allows end users to update database information via a front end.
We now need to support a new customer, but this customer has a slightly different specification; we will have changes to a number of tables' columns and datatypes.
We don't want to combine into one table, as this bloats up the database with lots of NULL columns (there will be 10+ unique columns per customer in some table).
The front end we can handle easily enough, as we just convert to and from JSON and the front end has been implemented per-customer from the ground up. But the backend is a bit more complicated.
We have tried a prototype where we override two tables at runtime; we converted two corresponding model classes to interfaces and implemented a concrete class per customer, loaded via the Spring configuration, e.g for a "products" table, we tried:
package com.mycompany.generic.model;
public interface Product
and then
package com.mycompany.customera.model;
#Table(name="products")
public class CustomerAProduct implements Properties {
String colour;
int weight;
}
or
package com.mycompany.customerb.model;
#Table(name="products")
public class CustomerBProduct implements Properties {
String colour;
int volume;
Double price;
}
..where Spring loads, as a runtime option, com.mycompany.customera or customerb depending on configuration, along with any customer-specific validations/service classes to act on the new POJO's. You see that the underlying columns can be different.
However, I am hesitate to pitch into implementing this, because..
Almost every model class will need converting and implementing per-customer, not just the ones that are different. This is because we have many joins (OneToMany etc) within the model classes, Hibernate does not let you join to an interface (eg HHH-4338)
some sort of util/factory is required to generate new instances of classes, as where we used to do new Properties we do not know whether to use new CustomerAProperties() or new CustomerBProperties() (for the same reason, we cannot use TargetEntity to solve the above problem, because this requires a .class file which cannot be set in the code)
These seem pretty major downsides so I am trying to research a better way to do it. We can build per-customer, via Maven, but then I am not sure how to implement this in a way that isn't going to break Eclipse while we develop locally..
Or, is there some other method that I am not aware of ?
thanks in advance for any suggestions or pointers on what to research etc.
Or, is there some other method that I am not aware of ?
Any reason you cannot switch from annotation based mapping to xml mapping?
Each customer gets a set of XML mapping files. Now you only need to subclass when the model truly differs between customers.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I’m working on a little multi-tier application utilizing JPA/EclipseLink as a persistence layer. In my current design I have two sets of objects, POJOs and Entity objects, I use POJOs for general programming tasks and Entity classes are used for DB read/write and table mapping.
Now is it necessary to have POJO=>Entity mapping (problematically) and then a second Entity==>DB tables mapping (JPA annotations)? I find it easier to just use Entity classes as my main java objects and persist them whenever necessary, after all Entity classes are essentially POJO with with couple of JPA annotations.
Also in a situation where it's indeed necessary to keep things separated, what is the best place to do the POJO=>Entity mapping, currently I do this in a CRUD method, e.g.
public void addCustomerPOJO(Customer customerPOJO){
//Cteat EntityManager and start a Transaction
//Create Entity class and populate it with values
//from the passed-in regular (non entity) Customer class
//Persiste and close
}
Is there a better or more common way to do this?
There is nothing wrong with using your entities as your domain objects. You have to be aware of using entities that have been detached and whatnot, but that can be managed.
I would not artificially create work for yourself by forcing each entity to be mapped to another bean (or POJO). Sometimes it is necessary to wrap many entities (or values from entities) into a bean, but only do it if there is a good reason.
Maybe the confussion is due to the fact that the entity is just a POJO with the mappings info (in the code as annotations or in a separate configuration file). Works as a POJO as long as you want (you can create and modify objects; as long as you don't save them with a Session they won't be written in the DB).
Sometimes you might need to have the data in a bean that is not an Entity (mainly because that bean is managed by another framework and you do not want to mix things *1), then you only have to copy (by an specific constructor, by calling lots of set...(), whatever) that data from your bean to your Entity/POJO.
*1 I am thinking of JSF here.
I see no reason for two parallel object hierarchies like this. I'd have entities and ditch what you're calling POJOs. No need for mapping. It's a waste of CPU cycles for no benefit that I can see.
I am currently working on a three-tired Java EE app with JPA serving the back end. I use a single java class to represent each table in the database(entity classes) And i use the same classes to do all the operations, both in the business layer as well as the database layer. And it makes sense too.
Because in all the three layers, you can create an instance of the same entity class independently.
PS - #Hay : Even when i started learning JPA, I was doing manipulations with two different sets of same classes as you :) I guess, this practice emerged becoz of EJB 2.1 which didn't have any annotations in them. So basically two different sets of classes are required where one has to be entirely dedicated as ENTITY CLASSES for DAO operations.
As JPA evolved, Annotations are brought into picture, which made our lives easy.. OLD HABBITS DIE HARD indeed ;)
Annotations do have their downside, especially in multi-tiered Java EE applications.
In the example below, you have a simple POJO object (Domain object) which you want
the java REST clients to use
the REST server accepts this object as a parameter, and
to persist this object to a database.
I would think this is a common use-case.
With so many annotations the clients using this object needs all the jar dependencies. I suppose the annotations can be moved to an XML file, but then the annotation advantages are lost.
Are there any other creative solutions?
#Data
#Entity
#XmlRootElement(name="sport")
#Table(name = "db_sport")
#NamedQueries({
#NamedQuery(name = "Sport.findAll", query = "SELECT d FROM Sport d")})
public class Sport implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Basic(optional = false)
#Column(name = "sportId")
int sportId;
}
You may need to use another set of classes to prevent ripple effect. This is often the case with web services that have several dependencies. Data mapping in general adds to complexity of program and should be avoided without a valid reason.
My $0.20
Unless you can remember how relationships are marked in your code and
when they are populated by hibernate and when/where they are accessed
in the code I would suggest you to go with DTO approach.
However, if you are learning hibernate or going to use it in small project it may be easy for you to return the entity (or a collection of them) from your controller layer.
But I'm sure the more you do it the more you will find the need to
move to DTO or even JsonView. If you are not the one who is
building UI then you will realize it even sooner.
Speaking of DTO, my fav is ModelMapper. You can do conversion (simple and complex whatever you like) at controller layer. This way you will know what you are returning inside the DTO.
See the slides of JPA Best Practices of Lee Chuk Munn. You can find it in JPA Best Practices - Indo Java Podcast.
Ruby on Rails has polymorphic relations which are really useful for implementing functionality such as commenting, tagging and rating to name a few. We can have a comment, tag or rating class which has a many to one polymorphic relationship with a commentable, taggable and rateable object. Also, a given domain object can choose to implement any combination of such relations. So, it can for example be commentable, taggable and rateable at the same time.
I couldn't think up of a straightforward way to duplicate this functionality in Hibernate. Ideally, there would be a Comment class which will have a many to one relationship with a Commentable class and a Commentable class will conversely have a one to many relationship with Comments. It will be ideal if the concrete domain classes can inherit from a number of such classes, say Commentable and Taggable. Things seem a little complicated as a Java class can only extend one other class and some code might end up being duplicated across a number of classes.
I wanted to know what are the best practices for modeling such relationships neatly and concisely using Hibernate?
It seems to me that your question is not hibernate specific but more on the lines of "how can I get around the single inheritance model?"
If implementing interfaces is not what you have in mind AOP (Aspect Oriented Programming) might provide a way for you to do what you wish.