diff --git a/pom.xml b/pom.xml index dc89bad7cf6212c6c6bc48fea2a7bb37751ca979..22b57e705be0d3ca1ffdd326dc8e7d89ba56f5cb 100755 --- a/pom.xml +++ b/pom.xml @@ -171,6 +171,7 @@ </exclusion> </exclusions> </dependency> + <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> diff --git a/src/main/java/no/nibio/vips/logic/entity/CropCategory.java b/src/main/java/no/nibio/vips/logic/entity/CropCategory.java index c1c588f79b03f05c3cb8d77af87f811c9d42cf91..43cc458731c8f1194194a494ec5fe27b2659be7b 100755 --- a/src/main/java/no/nibio/vips/logic/entity/CropCategory.java +++ b/src/main/java/no/nibio/vips/logic/entity/CropCategory.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.Id; @@ -38,6 +37,9 @@ import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -46,6 +48,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; @Entity @Table(name = "crop_category") @XmlRootElement +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) @NamedQueries({ @NamedQuery(name = "CropCategory.findAll", query = "SELECT c FROM CropCategory c"), @NamedQuery(name = "CropCategory.findByCropCategoryId", query = "SELECT c FROM CropCategory c WHERE c.cropCategoryId = :cropCategoryId"), @@ -67,7 +70,7 @@ public class CropCategory implements Serializable { private String defaultName; @OneToMany(cascade = CascadeType.ALL, mappedBy = "cropCategoryId", fetch = FetchType.EAGER) private Set<CropCategoryLocal> cropCategoryLocalSet; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "crop_organism_ids") private Integer[] cropOrganismIds; @Column(name = "organization_id") diff --git a/src/main/java/no/nibio/vips/logic/entity/CropPest.java b/src/main/java/no/nibio/vips/logic/entity/CropPest.java index 9ba62175dc51cb560291c5d608b466ebade6dfe3..0443494be304d26850ffadbd74bc9e4a32503eb2 100755 --- a/src/main/java/no/nibio/vips/logic/entity/CropPest.java +++ b/src/main/java/no/nibio/vips/logic/entity/CropPest.java @@ -21,7 +21,6 @@ package no.nibio.vips.logic.entity; import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; @@ -30,6 +29,9 @@ import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.xml.bind.annotation.XmlRootElement; import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -37,6 +39,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; */ @Entity @Table(name = "crop_pest") +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) @XmlRootElement @NamedQueries({ @NamedQuery(name = "CropPest.findAll", query = "SELECT c FROM CropPest c"), @@ -52,7 +55,7 @@ public class CropPest implements Serializable { @NotNull @Column(name = "crop_organism_id") private Integer cropOrganismId; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "pest_organism_ids") private Integer[] pestOrganismIds; @Column(name = "include_all_child_crops") diff --git a/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java b/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java index 57f09f879c1745d11eb25839d9c8da3645e2595f..a17f2fbadaa35794dd3de13e10a6883d024776f7 100755 --- a/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java +++ b/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java @@ -42,10 +42,13 @@ import javax.xml.bind.annotation.XmlTransient; import com.fasterxml.jackson.annotation.JsonIgnore; import java.util.List; import java.util.TimeZone; -import javax.persistence.Convert; import javax.persistence.Transient; import no.nibio.vips.logic.util.IntegerArrayUserType; import no.nibio.vips.util.WeatherUtil; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; + /** * @copyright 2014-2016 <a href="http://www.nibio.no/">NIBIO</a> * @author Tor-Einar Skog <tor-einar.skog@nibio.no> @@ -53,6 +56,7 @@ import no.nibio.vips.util.WeatherUtil; @Entity @Table(name = "forecast_configuration") @XmlRootElement +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) @NamedQueries({ @NamedQuery(name = "ForecastConfiguration.findAll", query = "SELECT f FROM ForecastConfiguration f WHERE f.isPrivate = FALSE"), @NamedQuery(name = "ForecastConfiguration.findByForecastConfigurationId", query = "SELECT f FROM ForecastConfiguration f WHERE f.forecastConfigurationId = :forecastConfigurationId"), @@ -81,8 +85,6 @@ import no.nibio.vips.util.WeatherUtil; @NamedQuery(name = "ForecastConfiguration.findByModelIdAndYear", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId = :modelId AND YEAR(f.dateStart) <= :year AND YEAR(f.dateEnd) >= :year AND f.isPrivate = FALSE") }) public class ForecastConfiguration implements Serializable, Comparable { - - @OneToMany(cascade = CascadeType.ALL, mappedBy = "forecastConfiguration", fetch = FetchType.EAGER) private Set<ForecastModelConfiguration> forecastModelConfigurationSet; private static final long serialVersionUID = 1L; @@ -122,7 +124,7 @@ public class ForecastConfiguration implements Serializable, Comparable { @Column(name = "is_private") private Boolean isPrivate; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "grid_weather_station_point_of_interest_ids") private Integer[] gridWeatherStationPointOfInterestIds; diff --git a/src/main/java/no/nibio/vips/logic/entity/Message.java b/src/main/java/no/nibio/vips/logic/entity/Message.java index 72cfa7935398248d51d71aff98ae70f8f2aab212..1bd92c6064cc3c72c991b02744860c7170b17a8f 100755 --- a/src/main/java/no/nibio/vips/logic/entity/Message.java +++ b/src/main/java/no/nibio/vips/logic/entity/Message.java @@ -27,7 +27,6 @@ import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -45,7 +44,9 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.xml.bind.annotation.XmlRootElement; import no.nibio.vips.logic.util.IntegerArrayUserType; - +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2014 <a href="http://www.nibio.no/">NIBIO</a> @@ -54,6 +55,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; @Entity @Table(name = "message") @XmlRootElement +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) @NamedQueries({ @NamedQuery(name = "Message.findAll", query = "SELECT m FROM Message m"), @NamedQuery(name = "Message.findByMessageId", query = "SELECT m FROM Message m WHERE m.messageId = :messageId"), @@ -274,7 +276,7 @@ public class Message implements Serializable { /** * @return the cropCategoryIds */ - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name="crop_category_ids") public Integer[] getCropCategoryIds() { return cropCategoryIds; diff --git a/src/main/java/no/nibio/vips/logic/entity/Observation.java b/src/main/java/no/nibio/vips/logic/entity/Observation.java index f380af923b48b2ec9289fb3dcc57c127ff76c48e..54fbc58b67016d2fed44542209dca50f133c3def 100755 --- a/src/main/java/no/nibio/vips/logic/entity/Observation.java +++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java @@ -42,7 +42,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.CascadeType; -import javax.persistence.Convert; import javax.persistence.FetchType; import javax.persistence.OneToMany; import javax.validation.constraints.Size; @@ -51,7 +50,9 @@ import no.nibio.vips.gis.GISUtil; import no.nibio.vips.logic.entity.rest.ObservationListItem; import no.nibio.vips.logic.util.StringJsonUserType; import no.nibio.vips.observationdata.ObservationDataSchema; - +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -60,6 +61,7 @@ import no.nibio.vips.observationdata.ObservationDataSchema; @Entity @Table(name = "observation") @XmlRootElement +@TypeDefs( {@TypeDef( name= "StringJsonObject", typeClass = StringJsonUserType.class)}) @NamedQueries({ @NamedQuery(name = "Observation.findAll", query = "SELECT o FROM Observation o"), @NamedQuery(name = "Observation.findByObservationId", query = "SELECT o FROM Observation o WHERE o.observationId = :observationId"), @@ -438,7 +440,7 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse /** * @return the observationData */ - @Convert(converter = StringJsonUserType.class) + @Type(type = "StringJsonObject") @Column(name = "observation_data") @Override public String getObservationData() { diff --git a/src/main/java/no/nibio/vips/logic/entity/UserUuidPK.java b/src/main/java/no/nibio/vips/logic/entity/UserUuidPK.java index d48b50282535fd49174618f8c3e0679b4091ec0d..9168cdfb5975ed16ce379896cea825c02d4f9430 100755 --- a/src/main/java/no/nibio/vips/logic/entity/UserUuidPK.java +++ b/src/main/java/no/nibio/vips/logic/entity/UserUuidPK.java @@ -34,6 +34,7 @@ public class UserUuidPK implements Serializable { @Basic(optional = false) @NotNull @Column(name = "user_uuid") + @org.hibernate.annotations.Type(type="pg-uuid") // Ugly implementation specific hack private UUID userUuid; @Basic(optional = false) @NotNull diff --git a/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java index 46d7b8747f2077dae55a9611e29a41634ff0fd55..157953ea0393c5cc3bdd972b7433c9e5ba5f1d21 100755 --- a/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java @@ -21,11 +21,13 @@ package no.nibio.vips.logic.messaging; import java.util.List; import javax.persistence.Basic; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -33,6 +35,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; */ @Entity @Table(name = "forecast_event_notification_subscription", schema = "messaging") +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) public class ForecastEventNotificationSubscription { @Id @@ -43,11 +46,11 @@ public class ForecastEventNotificationSubscription { @Column(name = "universal_message_format_id") private Integer universalMessageFormatId; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "weather_station_ids") private Integer[] weatherStationIds; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "crop_category_ids") private Integer[] cropCategoryIds; diff --git a/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java index ee56bbd568444eb1a80895b60f6572bb3df114f6..2231f3b146004522386b65ef5450cef57efc925e 100755 --- a/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java @@ -22,12 +22,13 @@ import java.io.Serializable; import java.util.List; import javax.persistence.Basic; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import no.nibio.vips.logic.util.IntegerArrayUserType; - +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -35,6 +36,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; */ @Entity @Table(name = "message_notification_subscription", schema = "messaging") +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) public class MessageNotificationSubscription implements Serializable { @Id @@ -45,11 +47,11 @@ public class MessageNotificationSubscription implements Serializable { @Column(name = "universal_message_format_id") private Integer universalMessageFormatId; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "message_tag_ids") private Integer[] messageTagIds; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "crop_category_ids") private Integer[] cropCategoryIds; diff --git a/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java index f4e41029077d3fdb8c9205e5c2f076b917ac086a..7df24d956a44b400a0cacbd53660cef00e7cd2fc 100755 --- a/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java @@ -22,11 +22,13 @@ import java.io.Serializable; import java.util.List; import javax.persistence.Basic; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -34,6 +36,7 @@ import no.nibio.vips.logic.util.IntegerArrayUserType; */ @Entity @Table(name = "observation_notification_subscription", schema = "messaging") +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) public class ObservationNotificationSubscription implements Serializable { @Id @@ -44,7 +47,7 @@ public class ObservationNotificationSubscription implements Serializable { @Column(name = "universal_message_format_id") private Integer universalMessageFormatId; - @Convert(converter = IntegerArrayUserType.class) + @Type(type = "IntegerArray") @Column(name = "crop_category_ids") private Integer[] cropCategoryIds; diff --git a/src/main/java/no/nibio/vips/logic/messaging/UniversalMessage.java b/src/main/java/no/nibio/vips/logic/messaging/UniversalMessage.java index 8b6e704e4750b0e3d11b8cf4cdfd49e1ad95c76b..db8020bf17a7cccac787569541a1592fd6d04065 100755 --- a/src/main/java/no/nibio/vips/logic/messaging/UniversalMessage.java +++ b/src/main/java/no/nibio/vips/logic/messaging/UniversalMessage.java @@ -46,9 +46,10 @@ import javax.persistence.Transient; import javax.xml.bind.annotation.XmlRootElement; import com.ibm.icu.util.ULocale; -import javax.persistence.Convert; import no.nibio.vips.logic.util.StringJsonUserType; - +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -57,6 +58,7 @@ import no.nibio.vips.logic.util.StringJsonUserType; @Entity @Table(name = "universal_message", schema = "messaging") @XmlRootElement +@TypeDefs( {@TypeDef( name= "StringJsonObject", typeClass = StringJsonUserType.class)}) @NamedQueries({ @NamedQuery(name = "UniversalMessage.findAll", query = "SELECT u FROM UniversalMessage u"), @NamedQuery(name = "UniversalMessage.findByUniversalMessageId", query = "SELECT u FROM UniversalMessage u WHERE u.universalMessageId = :universalMessageId"), @@ -74,11 +76,11 @@ public class UniversalMessage implements Serializable { //@Column(name = "distribution_list", columnDefinition = "json") //@Convert(converter = PostgresJSONStringConverter.class) // Documentation on StackOverflow: http://stackoverflow.com/questions/15974474/mapping-postgresql-json-column-to-hibernate-value-type - @Convert(converter = StringJsonUserType.class) + @Type(type = "StringJsonObject") @Column(name = "distribution_list") private String distributionList; - @Convert(converter = StringJsonUserType.class) + @Type(type = "StringJsonObject") @Column(name = "message_local_versions") private String messageLocalVersions; diff --git a/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java b/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java index ef99793a431cfc0fc0dca3fe357e3f527a7e185a..94ea3338fd130ee6b915935a663404cfca488ee2 100755 --- a/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java +++ b/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java @@ -24,7 +24,6 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import java.util.Arrays; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -36,41 +35,41 @@ import org.hibernate.usertype.UserType; * @author Tor-Einar Skog <tor-einar.skog@nibio.no> */ -public class IntegerArrayUserType implements UserType<Integer[]> { +public class IntegerArrayUserType implements UserType { - public IntegerArrayUserType() - { - super(); + /** + * Return the SQL type codes for the columns mapped by this type. The + * codes are defined on <tt>java.sql.Types</tt>. + * + * @return int[] the typecodes + * @see java.sql.Types + */ + @Override + public int[] sqlTypes() { + return new int[] { Types.ARRAY }; } + /** * The class returned by <tt>nullSafeGet()</tt>. * * @return Class */ @Override - public Class<Integer[]> returnedClass() { + public Class returnedClass() { return Integer[].class; } - /** - * Are objects of this type mutable? + * Compare two instances of the class mapped by this type for persistence "equality". + * Equality of the persistent state. * + * @param x + * @param y * @return boolean */ @Override - public boolean isMutable() { - return true; - } - - - @Override - public int getSqlType() { - return Types.ARRAY; - } + public boolean equals(Object x, Object y) throws HibernateException { - @Override - public boolean equals(Integer[] x, Integer[] y) { if( x== null){ return y== null; @@ -79,41 +78,163 @@ public class IntegerArrayUserType implements UserType<Integer[]> { return x.equals( y); } + /** + * Get a hashcode for the instance, consistent with persistence "equality" + */ @Override - public int hashCode(Integer[] j) { - return Arrays.hashCode(j); + public int hashCode(Object x) throws HibernateException { + + return x.hashCode(); } - @Override - public void nullSafeSet(PreparedStatement ps, Integer[] j, int i, SharedSessionContractImplementor ssci) throws SQLException { - if (j == null) { - ps.setNull(i, Types.OTHER); + /** + * Retrieve an instance of the mapped class from a JDBC resultset. Implementors + * should handle possibility of null values. + * + * @param rs a JDBC result set + * @param names the column names + * @param session + * @param owner the containing entity @return Object + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ + //@Override + public Object nullSafeGet( + ResultSet rs, + String[] names, + SessionImplementor session, + Object owner) throws HibernateException, SQLException { + if (rs.wasNull()) { + return null; + } + + try + { + Integer[] array = (Integer[]) rs.getArray(names[0]).getArray(); + return array; + } + catch(NullPointerException ex) + { + return new Integer[0]; + } + } + + /** + * Write an instance of the mapped class to a prepared statement. Implementors + * should handle possibility of null values. A multi-column type should be written + * to parameters starting from <tt>index</tt>. + * + * @param st a JDBC prepared statement + * @param value the object to write + * @param index statement parameter index + * @param session + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ + //@Override + public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { + if (value == null) { + st.setNull(index, Types.OTHER); return; } - Integer[] castObject = (Integer[]) j; - Array array = ssci.getJdbcConnectionAccess().obtainConnection().createArrayOf("integer", castObject); // The postgres array data type - ps.setArray(i, array); + Integer[] castObject = (Integer[]) value; + Array array = session.connection().createArrayOf("integer", castObject); // The postgres array data type + st.setArray(index, array); + } + + /** + * Return a deep copy of the persistent state, stopping at entities and at + * collections. It is not necessary to copy immutable objects, or null + * values, in which case it is safe to simply return the argument. + * + * @param value the object to be cloned, which may be null + * @return Object a copy + */ + @Override + public Object deepCopy(Object value) throws HibernateException { + + return value; } + /** + * Are objects of this type mutable? + * + * @return boolean + */ @Override - public Integer[] deepCopy(Integer[] j) { - return j; + public boolean isMutable() { + return true; } + /** + * Transform the object into its cacheable representation. At the very least this + * method should perform a deep copy if the type is mutable. That may not be enough + * for some implementations, however; for example, associations must be cached as + * identifier values. (optional operation) + * + * @param value the object to be cached + * @return a cachable representation of the object + * @throws org.hibernate.HibernateException + * + */ @Override - public Serializable disassemble(Integer[] j) { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + public Serializable disassemble(Object value) throws HibernateException { + return (Integer[])this.deepCopy( value); } + /** + * Reconstruct an object from the cacheable representation. At the very least this + * method should perform a deep copy if the type is mutable. (optional operation) + * + * @param cached the object to be cached + * @param owner the owner of the cached object + * @return a reconstructed object from the cachable representation + * @throws org.hibernate.HibernateException + * + */ @Override - public Integer[] nullSafeGet(ResultSet rs, int i, SharedSessionContractImplementor ssci, Object o) throws SQLException { + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return this.deepCopy( cached); + } + + /** + * During merge, replace the existing (target) value in the entity we are merging to + * with a new (original) value from the detached entity we are merging. For immutable + * objects, or null values, it is safe to simply return the first parameter. For + * mutable objects, it is safe to return a copy of the first parameter. For objects + * with component values, it might make sense to recursively replace component values. + * + * @param original the value from the detached entity being merged + * @param target the value in the managed entity + * @return the value to be merged + */ + @Override + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return original; + } + + /** + * Retrieve an instance of the mapped class from a JDBC resultset. Implementors + * should handle possibility of null values. + * + * @param rs a JDBC result set + * @param strings the column names + * @param ssci + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ + @Override + public Object nullSafeGet(ResultSet rs, String[] strings, SharedSessionContractImplementor ssci, Object o) throws HibernateException, SQLException { if (rs.wasNull()) { return null; } try { - Integer[] array = (Integer[]) rs.getArray(i).getArray(); + Integer[] array = (Integer[]) rs.getArray(strings[0]).getArray(); return array; } catch(NullPointerException ex) @@ -122,12 +243,30 @@ public class IntegerArrayUserType implements UserType<Integer[]> { } } + /** + * Write an instance of the mapped class to a prepared statement. Implementors + * should handle possibility of null values. A multi-column type should be written + * to parameters starting from <tt>index</tt>. + * + * @param ps a JDBC prepared statement + * @param o the object to write + * @param i statement parameter index + * @param ssci + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ @Override - public Integer[] assemble(Serializable srlzbl, Object o) { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } + public void nullSafeSet(PreparedStatement ps, Object o, int i, SharedSessionContractImplementor ssci) throws HibernateException, SQLException { + if (o == null) { + ps.setNull(i, Types.OTHER); + return; + } - + Integer[] castObject = (Integer[]) o; + Array array = ssci.connection().createArrayOf("integer", castObject); // The postgres array data type + ps.setArray(i, array); + } } diff --git a/src/main/java/no/nibio/vips/logic/util/JsonPostgreSQLDialect.java b/src/main/java/no/nibio/vips/logic/util/JsonPostgreSQLDialect.java new file mode 100755 index 0000000000000000000000000000000000000000..2e7dda6a31abe3dec1d7ec726d5e07ad6fbb52d1 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/util/JsonPostgreSQLDialect.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 NIBIO <http://www.nibio.no/>. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +package no.nibio.vips.logic.util; + +import java.sql.Types; +import org.hibernate.dialect.PostgreSQL9Dialect; + +/** + * @copyright 2015 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class JsonPostgreSQLDialect extends PostgreSQL9Dialect{ + public JsonPostgreSQLDialect() { + + super(); + + this.registerColumnType(Types.JAVA_OBJECT, "json"); + } +} diff --git a/src/main/java/no/nibio/vips/logic/util/StringJsonUserType.java b/src/main/java/no/nibio/vips/logic/util/StringJsonUserType.java index 2b36426c599a9173a6fa2778efce5a27c04c3a65..1672d607cbfc160fe8502e5482b303e656010a70 100755 --- a/src/main/java/no/nibio/vips/logic/util/StringJsonUserType.java +++ b/src/main/java/no/nibio/vips/logic/util/StringJsonUserType.java @@ -29,13 +29,23 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; /** - * @copyright 2015-2024 <a href="http://www.nibio.no/">NIBIO</a> + * @copyright 2015-2019 <a href="http://www.nibio.no/">NIBIO</a> * @author Tor-Einar Skog <tor-einar.skog@nibio.no> */ -public class StringJsonUserType implements UserType<String> { - +public class StringJsonUserType implements UserType { + /** + * Return the SQL type codes for the columns mapped by this type. The + * codes are defined on <tt>java.sql.Types</tt>. + * + * @return int[] the typecodes + * @see java.sql.Types + */ + @Override + public int[] sqlTypes() { + return new int[] { Types.JAVA_OBJECT}; + } /** * The class returned by <tt>nullSafeGet()</tt>. @@ -47,7 +57,53 @@ public class StringJsonUserType implements UserType<String> { return String.class; } + /** + * Compare two instances of the class mapped by this type for persistence "equality". + * Equality of the persistent state. + * + * @param x + * @param y + * @return boolean + */ + @Override + public boolean equals(Object x, Object y) throws HibernateException { + + if( x== null){ + + return y== null; + } + + return x.equals( y); + } + + /** + * Get a hashcode for the instance, consistent with persistence "equality" + */ + @Override + public int hashCode(Object x) throws HibernateException { + + return x.hashCode(); + } + /** + * Retrieve an instance of the mapped class from a JDBC resultset. Implementors + * should handle possibility of null values. + * + * @param rs a JDBC result set + * @param names the column names + * @param session + * @param owner the containing entity @return Object + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ + //@Override + public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { + if(rs.getString(names[0]) == null){ + return null; + } + return rs.getString(names[0]); + } /** * Write an instance of the mapped class to a prepared statement. Implementors @@ -79,12 +135,12 @@ public class StringJsonUserType implements UserType<String> { * * @param value the object to be cloned, which may be null * @return Object a copy - * + */ @Override public Object deepCopy(Object value) throws HibernateException { return value; - }*/ + } /** * Are objects of this type mutable? @@ -96,60 +152,95 @@ public class StringJsonUserType implements UserType<String> { return true; } + /** + * Transform the object into its cacheable representation. At the very least this + * method should perform a deep copy if the type is mutable. That may not be enough + * for some implementations, however; for example, associations must be cached as + * identifier values. (optional operation) + * + * @param value the object to be cached + * @return a cachable representation of the object + * @throws org.hibernate.HibernateException + * + */ @Override - public int getSqlType() { - return Types.JAVA_OBJECT; + public Serializable disassemble(Object value) throws HibernateException { + return (String)this.deepCopy( value); } + /** + * Reconstruct an object from the cacheable representation. At the very least this + * method should perform a deep copy if the type is mutable. (optional operation) + * + * @param cached the object to be cached + * @param owner the owner of the cached object + * @return a reconstructed object from the cachable representation + * @throws org.hibernate.HibernateException + * + */ @Override - public boolean equals(String x, String y) { - if( x== null){ - - return y== null; - } - - return x.equals( y); + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return this.deepCopy( cached); } + /** + * During merge, replace the existing (target) value in the entity we are merging to + * with a new (original) value from the detached entity we are merging. For immutable + * objects, or null values, it is safe to simply return the first parameter. For + * mutable objects, it is safe to return a copy of the first parameter. For objects + * with component values, it might make sense to recursively replace component values. + * + * @param original the value from the detached entity being merged + * @param target the value in the managed entity + * @return the value to be merged + */ @Override - public int hashCode(String j) { - return j.hashCode(); + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return original; } + + /** + * Retrieve an instance of the mapped class from a JDBC resultset. Implementors + * should handle possibility of null values. + * + * @param rs a JDBC result set + * @param strings the column names + * @param ssci + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ @Override - public String nullSafeGet(ResultSet rs, int i, SharedSessionContractImplementor ssci, Object o) throws SQLException { - if(rs.getString(i) == null){ + public Object nullSafeGet(ResultSet rs, String[] strings, SharedSessionContractImplementor ssci, Object o) throws HibernateException, SQLException { + if(rs.getString(strings[0]) == null){ return null; } - return rs.getString(i); + return rs.getString(strings[0]); } + /** + * Write an instance of the mapped class to a prepared statement. Implementors + * should handle possibility of null values. A multi-column type should be written + * to parameters starting from <tt>index</tt>. + * + * @param ps a JDBC prepared statement + * @param o the object to write + * @param i statement parameter index + * @param ssci + * @throws org.hibernate.HibernateException + * + * @throws java.sql.SQLException + */ @Override - public void nullSafeSet(PreparedStatement ps, String j, int i, SharedSessionContractImplementor ssci) throws SQLException { - if (j == null) { + public void nullSafeSet(PreparedStatement ps, Object o, int i, SharedSessionContractImplementor ssci) throws HibernateException, SQLException { + if (o == null) { ps.setNull(i, Types.OTHER); return; } - ps.setString(i, j); + ps.setObject(i, o, Types.OTHER); } - @Override - public String deepCopy(String j) { - return j; - } - - @Override - public Serializable disassemble(String j) { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } - - @Override - public String assemble(Serializable srlzbl, Object o) { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody - } - - - } diff --git a/src/main/java/no/nibio/vips/observationdata/ObservationDataSchema.java b/src/main/java/no/nibio/vips/observationdata/ObservationDataSchema.java index aa1da2bfadf1af6208c882a88129e1a4365812a0..7243432516effd348cc842f2ed91040e34d919cc 100755 --- a/src/main/java/no/nibio/vips/observationdata/ObservationDataSchema.java +++ b/src/main/java/no/nibio/vips/observationdata/ObservationDataSchema.java @@ -20,7 +20,6 @@ package no.nibio.vips.observationdata; import java.io.Serializable; import javax.persistence.Column; -import javax.persistence.Convert; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.NamedQueries; @@ -29,7 +28,8 @@ import javax.persistence.Table; import javax.xml.bind.annotation.XmlRootElement; import no.nibio.vips.logic.util.StringJsonUserType; import org.hibernate.annotations.Type; - +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> @@ -38,6 +38,7 @@ import org.hibernate.annotations.Type; @Entity @Table(name = "observation_data_schema") @XmlRootElement +@TypeDefs( {@TypeDef( name= "StringJsonObject", typeClass = StringJsonUserType.class)}) @NamedQueries({ @NamedQuery(name = "ObservationDataSchema.findAll", query = "SELECT o FROM ObservationDataSchema o"), @NamedQuery(name = "ObservationDataSchema.findByPK", query = "SELECT o FROM ObservationDataSchema o WHERE o.observationDataSchemaPK.organizationId = :organizationId AND o.observationDataSchemaPK.organismId = :organismId"), @@ -48,11 +49,11 @@ public class ObservationDataSchema implements Serializable { private static final long serialVersionUID = 1L; @EmbeddedId protected ObservationDataSchemaPK observationDataSchemaPK; - @Convert(converter = StringJsonUserType.class) + @Type(type = "StringJsonObject") @Column(name = "data_schema") private String dataSchema; - @Convert(converter = StringJsonUserType.class) - @Column(name = "data_model", columnDefinition="json") + @Type(type = "StringJsonObject") + @Column(name = "data_model") private String dataModel; public ObservationDataSchema() { diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 5e68097c77388a3ad6045f7545a729522701b408..bfaf5ef4a76f98b451cbbca7fad7c0c6981c4d71 100755 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -25,8 +25,8 @@ <jta-data-source>java:/jboss/datasources/vipslogic</jta-data-source> <class>no.nibio.vips.logic.messaging.MessageNotificationSubscription</class> <exclude-unlisted-classes>false</exclude-unlisted-classes> - <!--properties> - <property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisPG10Dialect"/> - </properties--> + <properties> + <property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/> + </properties> </persistence-unit> </persistence>