Reputation: 1780
I'm using hibernate to fetch some data from SQL Server 2014 database.
There is a Table which has columns of user-defined data types:
dbo.Nodos
Id (PK, int, not null)
Tipo (PK, FK, TipoNodo(tinyint), not null)
Nombre (varchar(40), null)
PosX (Coordenada(real), not null)
PosY (Coordenada(real), not null)
Label (varchar(8), not null)
Those data types are Coordenada and TipoNodo:
User-Defined Data Types
dbo.Coordenada (real, not null)
dbo.TipoNodo (tinyint, not null)
I'm mapping Nodos table as StopDTO class in Java:
@Entity
@Table(name = "Nodos")
public class StopDTO {
/*
* Atributos
*/
@Id
@Column(name = "Id", insertable = false, updatable = false)
private Integer id;
@Column(name = "Tipo", insertable = false, updatable = false)
private Integer tipo;
@Column(name = "Nombre", insertable = false, updatable = false)
private String nombre;
@Column(name = "PosX", insertable = false, updatable = false)
private Float posx;
@Column(name = "PosY", insertable = false, updatable = false)
private Float posy;
@Column(name = "Label", insertable = false, updatable = false)
private String label;
...
The problem comes when I query StopDTOs (using a NamedNativeQuery), I'm getting the following message:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: wrong column type encountered in column [PosX] in table [Nodos]; found [coordenada (Types#REAL)], but expecting [float (Types#FLOAT)] at org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateColumnType(SchemaValidatorImpl.java:165) at org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateTable(SchemaValidatorImpl.java:150) at org.hibernate.tool.schema.internal.SchemaValidatorImpl.performValidation(SchemaValidatorImpl.java:95) at org.hibernate.tool.schema.internal.SchemaValidatorImpl.doValidation(SchemaValidatorImpl.java:62) ...
Is this problem solved by implementing a couple of UserTypes for Coordenada and TipoNodo? What can I do if it's not?
Thank you!
Upvotes: 0
Views: 1051
Reputation: 1780
Solved!
Indeed, it was what expected: develop a pair of UserType. I'll post the code in case somebody needs:
TipoNodoUserType
package com.mycompany.usertype;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.descriptor.java.ShortTypeDescriptor;
import org.hibernate.usertype.UserType;
public class TipoNodoUserType implements UserType {
public static final TipoNodoUserType INSTANCE = new TipoNodoUserType();
@Override
public int[] sqlTypes() {
return new int[] {Types.TINYINT};
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return Short.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return Objects.hashCode(x);
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
String columnName = names[0];
Short columnValue = (Short) rs.getObject(columnName);
return columnValue == null ? null : columnValue;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
if(value == null){
st.setNull( index, Types.TINYINT );
}else{
String stringValue = ShortTypeDescriptor.INSTANCE.toString((Short)value);
st.setString(index, stringValue);
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
CoordenadaUserType
package com.mycompany.usertype;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.descriptor.java.FloatTypeDescriptor;
import org.hibernate.usertype.UserType;
public class CoordenadaUserType implements UserType {
public static final CoordenadaUserType INSTANCE = new CoordenadaUserType();
@Override
public int[] sqlTypes() {
return new int[] {Types.REAL};
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return Float.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return Objects.hashCode(x);
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
String columnName = names[0];
Float columnValue = (Float) rs.getObject(columnName);
return columnValue == null ? null : columnValue;
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
if(value == null){
st.setNull( index, Types.REAL );
}else{
String stringValue = FloatTypeDescriptor.INSTANCE.toString((Float)value);
st.setString(index, stringValue);
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
StopDTO
@Entity
@Table(name = "Nodos")
public class StopDTO implements java.io.Serializable{
/*
* Atributos
*/
private static final long serialVersionUID = 8171715812406080593L;
@Id
@Column(name = "Id", insertable = false, updatable = false)
private Integer id;
@Id
@Column(name = "Tipo", insertable = false, updatable = false)
@Type(type = "com.mycompany.usertype.TipoNodoUserType")
private Short tipo;
@Column(name = "Nombre", insertable = false, updatable = false)
private String nombre;
@Column(name = "PosX", insertable = false, updatable = false)
@Type(type = "com.mycompany.usertype.CoordenadaUserType")
private Float posx;
@Column(name = "PosY", insertable = false, updatable = false)
@Type(type = "com.mycompany.usertype.CoordenadaUserType")
private Float posy;
@Column(name = "Label", insertable = false, updatable = false)
private String label;
...
// Don't forget to code an empty constructor, setters/getters for every attribute and implementing hashCode and equals methods (as we're implementing Serializable interface).
Upvotes: 0
Reputation: 97
Please check the dialect configured in Hibernate, it should be SQLServer2008Dialect.
Upvotes: 1