JPA\Hibernate: Persisted list of entities in Singleton - java

I have a singleton that manages a list of some entities in my DB.
public class SchedulledQueue {
List<MyEntity> entities;
}
I need to store this list in my database. So I want a single table that only contains entities from which my singleton could grab all data.
TABLE schedulled_queue
(
entity_id character varying(32),
CONSTRAINT schedulled_queue FOREIGN KEY (entity_id)
REFERENCES tbl_my_entity (entity_id) MATCH SIMPLE
)
Is there any way to map my singleton SchedulledQueue in Hibernate to achieve this? Or should I not bother with such thing?

If you have multiple SchedulledQueue objects then it makes sense to have one to many relation between SchedulledQueue and MyEntity.
Since your SchedulledQueue in singleton. I don't see any advantage of creating an entity of it.

So, I don't found another way, except to create another Entity and use it through DAO.
public class SchedulledQueue {
List<SchedulledQueueEntity> entities;
}
SchedulledQueueEntity {
MyEntity ent;
}
Also it provided ability to use some additional fields for entity in queue, that we needed some time later.

Related

Hibernate : Map single VO to two tables

I have two tables - Table1 and Table2. Data structure of both the tables is same.
I have single VO for both Table1 and Table2. I have two .hbm.xml file for two tables separately -
Table1.hbm.xml and Table2.hbm.xml
In my java code, based on a condition I either need to save to Table1 or Table2
if(someCondition)
{
session.saveOrUpdate(VO); //This should be for Table1
}
else
{
session.saveOrUpdate(VO); //This should be for Table2
}
My problem is since that VO is same, there will be conflict in deciding which table to save.
Is it possible to have same VO mapped to two tables?
Note: The reason why I have such a requirement is Table1 and Table2 are in separate tablespace. One is partitioned and the other is not.
There are couple of other reasons for such a weird requirement which is beyond my control to change the architecture now.
In my opinion using two entity managers is a bit too much. What you need is to have a good abstraction around the table.
You can map the same class as many times you want you just have to map it under different name.
Than one good Repository pattern working with the abstract entity (instead of the concrete one) combined with a Factory or Builder to generate the two objects will get the job done. If you follow this approach you will not need to have this IF-ELSE flow.
#MappedSuperClass
class AbstractMappedSomeTimes {
private mappedAttribute;
}
#Table("yourtablename")
public class MappedOnce extends AbstractEntity{
}
#Table("yourtablename")
public class MappedTwise extends AbstractEntity{
}
Than you can have Repository working with AbstractMappedSomeTimes types of objects. You can also create a Factory that will generate either MappedOnce objects or MappedTwise objects.

Hibernate query subtyped entity by natural-id

I use Hibernate and want to query for entities by their natural identifier. However, it seems not to be possible to have natural ids on subtypes. I have two classes A and B where B extends A:
class A {
long id;
}
class B extends A {
String naturalId;
}
A is mapped in Hibernate with its own identifier. B is mapped as joined subclass. However, it is not possible to map the natural identifier of B in Hibernate because the mapping of B is a subclass mapping.
Why is it not possible to have a natural identifier on the subclass B? Note that I don't want Hibernate to generate my database schema, I just want to have natural ids for fast cache hits.
Is there a way/a best practice to have natural ids on subtypes for fast second level cache querying?
Is this still possible when natural ids might get updated (change) in rare circumstances and the cache has to be maintained in a clustered Java EE environment?
NaturalId only make sense for base classes, because you can't retrieve a sub-class without the base class info.
Let's say you could map map both the base class and the sub-class with a natural-id:
class A {
long id;
String baseId;
}
class B extends A {
String naturalId;
}
A a = session.bySimpleNaturalId( A.class ).load( "abc" );
If the entity we retrieve if of type B, it's not clear which of the natural-id variants will be used.
You can't fetch a sub-class without getting the base-class info. So when you load a Sub-class from cache, the associated base-class info is retrieved as well. Therefore you could have the base class store the natural-id, or simply use the primary key for caching.
You can update the natural-id, although a business key should be immutable. For mutable natural-ids you need to use the mutable attribute.
According to 13.3. Entity inheritance and second-level cache mapping:
As of Hibernate ORM 5.3, you can now override a base class #Cacheable
or #Cache definition at subclass level.
so you might have a chance by resetting the caching annotations on B.
I never tried it so please confirm the solution with a comment.

A class modeling a M:N relationship in Java: remember instances or just primary keys?

I have a class Lease modeling a relationship between classes Customer and VideoGame. Pretty simple and straightforward; it looks something like this:
class Lease() {
private VideoGame videoGame;
private Customer customer;
// etc.
public Lease(VideoGame videoGame, Customer customer) {
this.videoGame = videoGame;
this.customer = customer;
}
}
Each of the three classes is represented by a database table with an autogenerated index and additionaly the leases table has a foreign key to reference both Customer and VideoGame.
While retrieving a Lease from the database, should I...
proceed to retrieve both VideoGame and Lease instances in my getLease(long id) method, and store those objects in the Lease instance
or, is it better for the Lease class only to remember the "foreign keys" and I should only actually retrieve a instance of Customer and VideoGame when needed? This would require the Lease class to change to
class Lease() {
long videoGame;
long customer;
// etc.
}
The first approach seems more natural, however I'm looking for some "best practices" kind of advice on this. Thank you!
If you are using ORM framework (Hibernate, JPA etc) you should create classes relationship as you want, i.e. typically using class-to-class relationship. The framwork is responsible on creating queries and saving primary keys in DB tables.
If you do not use any framework it is up to you where to convert keys to objects and how to create you model, however using objects in model is more natural.

How can I manage to create a many-to-many relationship. The generated entity will have extra attributes.

I have 2 entities: Class(of students) and Student. A student can be in many classes(like in college) and a class has many students. The problem is how to ensure that this entity, generated in the middle, has 2 primary keys, the ids of each other entity (Student and Class).
I need to know how to create it using annotations. I use EJB3 and JPA Annotations in the project.
First, you don't need a middle entity. You have two entities and a join table between them.
You need a middle entity only if you have additional information about the relation - for example a StudentClass may have timesAbsent column.
In case you really need the third entity, you can have:
an #EmbeddedId, where you define a separate class holding the two parts of the primary key. That class must be #Embeddable
an #IdClass which will let you specify two #Id fields. You'll again need another class to hold the two fields representing the key.
See this question for which option to choose.
Note that you thus have a composite primary key, not two primary keys (which you can't have)
I know how to make this happen using hibernate. May be it'll help.
Make the collection type Set.
public class CollegeClass {
private Set<Student> students;
}
public class Student {
private Set<CollegeClass> classes;
}

Hibernate best approach for one Java class and multiple tables?

Put another way: How do you model/map a heavily reused child class/table to many different parent entities?
I have several entity types each being persisted into its own table:
class A --> table A
class B --> table B
....
Now I need to make each of these classes the parent of a 1:M unidirectional child collection. The collection is a history of approvals the entity has gained over time. The Child domain class is called "ApprovalItem". The Approval class is exactly the same for all types of parents.
What is the best way to map this? If I create a single table to hold all ApprovalItems, then I can't enforce a FK relation to the PK of the entity and/or I am left with a bad database design.
On the other hand, I could create an ApprovalIems table for each entity type (e.g. A_ApprovalItems, B_ApprovalItems, etc.). This seems like a good schema on the database side, but then it seems I need to create a separate domain classes in Java for each entity approval (e.g. AAprrovalItem class, BApprovalItem class, etc.). This seems like a lot of hassle and complexity to create so many new classes in Java that do nothing other than allow me to put in different JPA mapping annotations.
Is there a mapping technique in Hibernate that will allow me to have one class in Java map to several different tables depending on who the parent owner of the collection is?
I could create an ApprovalItem table for each entity type (e.g. A_ApprovalItem, B_ApprovalItem, etc.). This seems like a good schema on the database side
But
It seems i need to create a separate domain classes in Java for each entity approval (e.g. AAprrovalItem class, BApprovalItem class, etc.).
You do not need it. you can create a single ApprovalItem class and create a #OneToMany relationship between your parent classes and your ApprovalItem. Hibernate takes care to create a linked table for each relationship.
#Entity
public class ClassA {
#Id
#GeneratedValue
private Integer id;
// Hibernate will create CLASSA_APPROVALITEM to link both class
#OneToMany
private List<ApprovalItem> approvalItemList;
}
#Entity
public class ClassB {
#Id
#GeneratedValue
private Integer id;
// Hibernate will create CLASSB_APPROVALITEM to link both class
#OneToMany
private List<ApprovalItem> approvalItemList;
}
And your ApprovalItem class
#Entity
public class ApprovalItem {
#Id
#GeneratedValue
private Integer id;
// Nothing else
}
But Let's see what Java Persistence with Hibernate book talks about it
You may have shared references to the Bid objects. As suggested earlier, a User may have a collection of references to the Bid instances they made. You can’t delete an item and all its bids without removing these references first. You may get an exception if you try to commit this transaction, because a foreign key constraint may be violated.
So keep it in mind when dealing with shared references.
In order to see how the target schema looks like, you can use the following
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration
.addAnnotatedClass(ClassA.class)
.addAnnotatedClass(ClassB.class)
.addAnnotatedClass(ApprovalItem.class)
.setProperty(Environment.USER, <TYPE_YOUR_USER>)
.setProperty(Environment.PASS, <TYPE_YOUR_PASSWORD>)
.setProperty(Environment.URL, <TYPE_YOUR_URL>)
.setProperty(Environment.DIALECT, <TYPE_YOUR_DIALECT>)
.setProperty(Environment.DRIVER, <TYPE_YOUR_DRIVER>);
SchemaExport schema = new SchemaExport(configuration);
schema.setOutputFile("schema.sql");
schema.create(<DO_YOU_WANT_TO_PRINT_TO_THE_CONSOLE>, <DO_YOU_WANT_TO_EXPORT_THE_SCRIPT_TO_THE_DATABASE>);
It will generate a file called schema.sql, which contains your target schema
regards,
Chapter 8. Inheritance Mapping of Hibernate Documentation might help.
Otherwise, I see no problem having multiple ApprovalItem derived class that "do nothing", like you say, since it does differentiate the Approval, it's like having a type of approval. Seeing your model like so, I would recommend using multiple classes, even if they only inherit from your base ApprovalItem class.
Have I well understood your question or am I missing something else more subtle?

Categories