Detailed description of the unique field instance of the Hibernate identification database, hibernate Field
Detailed description of Hibernate database-specific field examples
Preface:
Hibernate provides built-in support for the vast majority of common database data types, but it is not enough to support exclusive fields of some databases. These special data types often provide better data expression capabilities than conventional data types, better suited to our business scenarios. For example, the Interval type of PostgreSQL allows you to conveniently store data for a period of time. This article takes adding support for the Interval type as an example to illustrate how to add support for the special data type for Hibernate.
Hibernate provides a wide range of data types, but the support for proprietary data types in some databases is limited. For example, the Interval type of PostgreSQL is very convenient for saving data of a "time period.
During development, we expect to map the Interval type to the Duration type of Java 8. However, by default, Hibernate maps the Duration type directly to the BigInt type of the database and directly saves the nanosecond value. Obviously, it is suitable for databases that do not directly support the Interval type, but we still expect to map it directly to the Interval Type of the database.
To this end, we need to adjust the ing between Hibernate for the two data types (Duration in the Java World and Interval in the Db world.
Fortunately, Hibernate provides a very convenient way to map data types.
Therefore, we need a class that implements the org. hibernate. usertype. UserType interface to implement data conversion/ ing between two worlds.
Custom type of Hibernate (UserType)
UserType is a custom data type interface provided by Hibernate. All user data must implement this interface, or select an appropriate interface from the interface defined in org. hibernate. usertype.
Given that our scenario is relatively simple, directly implementing UserType can meet your needs. This interface provides the following methods that need to be implemented by yourself:
Assemble (Serializable cached, Object owner)
Re-build (Java) objects from serialization.
DeepCopy (Object value)
Returns a deep copy.
Disassemble (Object value)
The serialized data of the conversion object.
Equals (Object x, Object y)
Returns whether the two ing data are equal.
HashCode (Object x)
Obtains the object hash.
IsMutable ()
Returns whether the object is of a variable type.
NullSafeGet (ResultSet rs, String [] names, Object owner)
Returns the corresponding Java object from the data of the database type. Core Implementation Method
NullSafeSet (PreparedStatement st, Object value, int index)
Returns data of the corresponding database type from a Java object. Core Implementation Method
Replace (Object original, Object target, Object owner)
During the merge, replace the target value in the object with the original value (original ).
ReturnedClass ()
Class returned by nullSafeGet.
SqlTypes ()
Returns the corresponding database type.
Instance
Package framework. postgresql; import org. hibernate. hibernateException; import org. hibernate. engine. spi. sharedSessionContractImplementor; import org. hibernate. usertype. userType; import org. postgresql. util. PGInterval; import java. io. serializable; import java. SQL. preparedStatement; import java. SQL. resultSet; import java. SQL. SQLException; import java. SQL. types; import java. time. duration;/*** PostgreSql Inteval field and java. time. duration ing * currently only supports the interval up to 1 month (30 days) * <p> * usage: * Add * \ @ TypeDef (name = "interval", typeClass = IntervalType to the object class. class) * added in field definition: * \ @ Type (type = "interval") * <p> * http://stackoverflow.com/questions/1945615/how-to-map-the-type-interval-in-hibernate/6139581#6139581 ** @ Version 1.0 * @ since 1.0 */public class IntervalType implements UserType {public Object assemble (Serializable cached, Object owner) throws HibernateException {return cached ;} public Object deepCopy (Object value) throws HibernateException {return value;} public Serializable disassemble (Object value) throws HibernateException {return (Serializable) value;} public boolean equals (Object arg 0, Object arg1) throws HibernateException {return arg0! = Null & arg1! = Null & arg0.equals (arg1) | arg0 = null & arg1 = null;} public int hashCode (Object object) throws HibernateException {return object. hashCode () ;}@ Override public Object nullSafeGet (ResultSet resultSet, String [] names, sessionImplementor, Object o) throws HibernateException, SQLException {String interval = resultSet. getString (names [0]); if (resultSet. wasNull () | interval = null) {return null;} PGInterval pgInterval = new PGInterval (interval); return getDuration (pgInterval);} @ Override public void nullSafeSet (PreparedStatement st, object value, int index, SharedSessionContractImplementor sessionImplementor) throws HibernateException, SQLException {if (value = null) {st. setNull (index, Types. OTHER);} else {// this http://postgresql.1045698.n5.nabble.com/Inserting-Information-in-PostgreSQL-interval-td2175203.html#a2175205 Duration duration = (Duration) value; st. setObject (index, getInterval (duration), Types. OTHER) ;}} public static Duration getDuration (PGInterval pgInterval) {return Duration. ofSeconds (pgInterval. getDays () * 24*3600 + pgInterval. getHours () * 3600 + pgInterval. getMinutes () * 60 + (int) pgInterval. getSeconds ();} private static PGInterval getInterval (Duration value) {long seconds = value. getSeconds (); int days = (int) (seconds/(24*3600); seconds-= days * 24*3600; int hours = (int) (seconds/3600); seconds-= hours * 3600; int minutes = (int) (seconds/60); seconds-= minutes * 60; seconds = Math. abs (seconds); return new PGInterval (0, 0, days, hours, minutes, seconds);} public boolean isMutable () {return false;} public Object replace (Object original, object target, Object owner) throws HibernateException {return original;} public Class returnedClass () {return Duration. class;} public int [] sqlTypes () {return new int [] {Types. OTHER };}}
Use custom type
So far, we have defined our own data types. However, Hibernate does not know how to use it. Therefore, we need to use TypeDef Annotation on Entity and Type Annotation on attributes.
For example:
...@Entity@TypeDef(name = "interval", typeClass = IntervalType.class)public class PaperStatis implements Serializable {... @Column(name = "avg_duration") @Type(type = "interval") public Duration getAvgDuration() { return this.avgDuration; }...}
Thank you for reading this article. I hope it will help you. Thank you for your support for this site!