用户定义的数据类型遇到错误的列类型

时间:2016-09-16 08:34:41

标签: java hibernate sql-server-2014

我正在使用hibernate从SQL Server 2014数据库中获取一些数据。

有一个表包含用户定义数据类型的列:

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)

这些数据类型是Coordenada和TipoNodo:

User-Defined Data Types
    dbo.Coordenada (real, not null)
    dbo.TipoNodo (tinyint, not null)

我将Nodos表映射为Java中的StopDTO类:

@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;
    ...

当我查询StopDTOs(使用NamedNativeQuery)时出现问题,我收到以下消息:

  

引起:org.hibernate.tool.schema.spi.SchemaManagementException:   模式验证:在[PosX]列中遇到错误的列类型   表[Nodos];发现[coordenada(Types#REAL)],但期待[浮动   (类型#FLOAT)]在   org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateColumnType(SchemaValidatorImpl.java:165)     在   org.hibernate.tool.schema.internal.SchemaValidatorImpl.validateTable(SchemaValidatorImpl.java:150)     在   org.hibernate.tool.schema.internal.SchemaValidatorImpl.performValidation(SchemaValidatorImpl.java:95)     在   org.hibernate.tool.schema.internal.SchemaValidatorImpl.doValidation(SchemaValidatorImpl.java:62)   ...

通过为Coordenada和TipoNodo实现几个UserTypes来解决这个问题吗?如果不是,我该怎么办?

谢谢!

2 个答案:

答案 0 :(得分:1)

请检查Hibernate中配置的方言,它应该是SQLServer2008Dialect。

答案 1 :(得分:0)

解决!

确实,这是预期的:开发一对UserType。如果有人需要,我会发布代码:

<强> 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).