15

次のようにStatusという名前の列挙型クラスがあります

public enum Status {
    PENDING(0), SUCCESS(1), FAILED(-1);

    private int st;

    private Status(int st){
        this.st = st;
    }
}

そして他のクラスから私はこのステータス列挙型をマップしようとします

public void setStatus(Status status) {
        this.status = status;
    }

    @Enumerated(EnumType.ORDINAL)
    public Status getStatus() {
        return status;
    }

このコードを実行すると、

java.lang.IllegalArgumentException:enumクラスデータの不明な順序値。ステータス:org.hibernate.type.EnumType.nullSafeGet(EnumType.java:93)の-1 org.hibernate.type.CustomType.nullSafeGet(CustomType.java: 124)org.hibernate.type.AbstractType.hydrate(AbstractType.java:106)で

しかし、列挙型の定義にはすでに-1があります。

4

3 に答える 3

12

UserTypeHibernateがこれらの列挙型をマップする方法を定義する独自の定義を行うことができます。

序数は列挙値のインデックスを定義するためFAILED、序数2になることに注意してください。そのプロパティを使用して列挙型をマップするには、UserType実装が必要です。

いくつかのリンク:

于 2012-07-16T11:31:49.523 に答える
10

これは、int idの代わりに文字列ラベルを使用するソリューションですが、適応するのは簡単です。

public class User { 
    @Id
    private int id;

    @Type(type = "com.example.hibernate.LabeledEnumType")
    private Role role;
}


public enum Role implements LabeledEnum {
    ADMIN("admin"), USER("user"), ANONYMOUS("anon");

    private final String label;

    Role(String label) {
        this.label = label;
    }

    @Override
    public String getLabel() {
        return label;
    }
}


public interface LabeledEnum {
    String getLabel();
}


public final class LabeledEnumType implements DynamicParameterizedType, UserType {

    private Class<? extends Enum> enumClass;

    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return cached;
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        return x == y;
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x == null ? 0 : x.hashCode();
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException {
        String label = rs.getString(names[0]);
        if (rs.wasNull()) {
            return null;
        }
        for (Enum value : returnedClass().getEnumConstants()) {
            if (value instanceof LabeledEnum) {
                LabeledEnum labeledEnum = (LabeledEnum) value;
                if (labeledEnum.getLabel().equals(label)) {
                    return value;
                }
            }
        }
        throw new IllegalStateException("Unknown " + returnedClass().getSimpleName() + " label");
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
            throws HibernateException, SQLException {
        if (value == null) {
            st.setNull(index, Types.VARCHAR);
        } else {
            st.setString(index, ((LabeledEnum) value).getLabel());
        }
    }

    @Override
    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }

    @Override
    public Class<? extends Enum> returnedClass() {
        return enumClass;
    }

    @Override
    public int[] sqlTypes() {
        return new int[]{Types.VARCHAR};
    }

    @Override
    public void setParameterValues(Properties parameters) {
        ParameterType params = (ParameterType) parameters.get( PARAMETER_TYPE );
        enumClass = params.getReturnedClass();
    }
}
于 2015-06-03T09:33:16.410 に答える
3

次の回避策を提案したいと思います。最初、私はそれが機能することに驚いていましたが、それは本当に簡単です:列挙型の場合:

    public enum Status {
    PENDING(0), SUCCESS(1), FAILED(-1);

    private int status;

    private Status(int status){
        this.status = status;
    }

    public String getStatus() {
        return status;
    }

    public static Status parse(int id) {
        Status status = null; // Default
        for (Status item : Status.values()) {
            if (item.getStatus().equals(id)) {
                Status = item;
                break;
            }
        }
        return Status;
    }
}

クラス

class StatedObject{

    @Column("status")
    private int statusInt;

    public Status getStatus() {
        return Status.parse(statusInt);
    }

    public void setStatus(Status paymentStatus) {
        this.statusInt = paymentStatus.getStatus();
    }

    public String getStatusInt() {
        return statusInt;
    }

    public void setStatusInt(int statusInt) {
        this.statusInt = statusInt;
    }
}

hibernate xmlファイルでhibernateを使用している場合は、次のようになります。

 <property name="statusInt "    column="status" type="java.lang.Integer" />

それだ

于 2016-09-14T14:44:37.177 に答える