📜 ⬆️ ⬇️

Hibernate duplicate fieldset


The problem that I would like to describe today is a repeating set of fields in Hibernate entities. Of course, it could be solved with the help of normalizing the database, but this is inconvenient when sampling and affects the speed, unnecessary joins for the sake of several columns are not needed by anyone.
So, let's imagine there is some kind of accounting system, in it in any entity it is important to keep history, who changed, who created, when there were recent changes, who created. In fact, in any project you can find similar sets and not one. As a result, when programmers create these fields, at best a copy-paste is obtained, and sometimes new names are born for the same fields.

I would like to consider two ways to solve this problem.

First way


This task can be solved using @Embeddable entities:

package ru.kabit.entity.embeded; import javax.persistence.Embeddable; import java.util.Date; @Embeddable public class HistoryFields { private Long lastModifierId; private Long creatorId; private Date lastModifyDate; private Date createDate; /* getters and setters */ } 

Remove removed fields from the class, insert one embedded property. In practice, walking through the code and adding an extra getter before calling these fields is easy, but in XML, JSP it is difficult to find all the places.
 package ru.kabit.entity; import ru.kabit.entity.embeded.HistoryFields; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Post { @Id @GeneratedValue private Long id; @Embedded private HistoryFields historyFields; /* getters and setters */ } 

If at least one field from HistoryFields is filled, then a HistoryFields object will be created and these fields will be filled, otherwise null will be in place of the object, which is by the way, very handy when writing logic. The names of the fields in the database can be different, so the @AttributeOverride annotation is used to change them.
')
The advantages of this approach:

Disadvantages :

Second way


The second solution is to use the @MappedSuperclass annotation:
 package ru.kabit.entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import java.util.Date; @MappedSuperclass public class HistoryEntity { @Id @GeneratedValue private Long id; private Long lastModifierId; private Long creatorId; private Date lastModifyDate; private Date createDate; /* getters and setters */ } 

Now there is a base class with a set of fields and when we see a similar set, you can simply follow it:
 package ru.kabit.entity; import javax.persistence.Entity; @Entity public class Table1 extends HistoryEntity { private Long otherFieldTable1; public Long getOtherFieldTable1() { return otherFieldTable1; } public void setOtherFieldTable1(Long otherFieldTable1) { this.otherFieldTable1 = otherFieldTable1; } } 

The advantages of this approach:

Disadvantages :

Conclusion


I described how to get rid of re-describing the set of fields in Hibernate entities, and also described the advantages and disadvantages of each. I hope that this article will be useful to you.

Source: https://habr.com/ru/post/180703/


All Articles