java Jpa 组合键可为空的列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/674104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:20:37  来源:igfitidea点击:

Jpa composite key nullable columns

javahibernatejpacomposite-id

提问by Miguel Ping

I'm using Hibernate's JPA impl to model some tables. I'm having trouble mapping a table that:

我正在使用 Hibernate 的 JPA impl 对一些表进行建模。我在映射一个表时遇到问题:

  • Has no primary key
  • Has a unique index on 4 columns, 3 of which can be nullable
  • 没有主键
  • 在 4 列上有唯一索引,其中 3 列可以为空

I tried to hack it and define the index as a composite Id, but since some columns are nullable this is not working properly. Is this possible with JPA/Hibernate?

我试图破解它并将索引定义为复合 Id,但由于某些列可以为空,因此无法正常工作。这可以用 JPA/Hibernate 实现吗?

Thanks

谢谢

采纳答案by Kevin Crowell

A work arround is... You should implements your own UserType implementation and treats the null value to return a representative Object for this.

一个工作是......您应该实现自己的 UserType 实现并处理空值以为此返回一个代表对象。

Look my example. The field is a nullable numeric, so my implementation is:

看我的例子。该字段是一个可为空的数字,所以我的实现是:

Looks like in HBM file:

在 HBM 文件中看起来像

   <key-property name="fieldName" type="mypackage.forUserTypes.DefaultLongType">
    <column name="FIELD_NAME" precision="10" scale="0" />
   </key-property>

...In Java:

...在 Java 中

public class DefaultLongType implements UserType {
private static final long serialVersionUID = 1L;

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
 */
public Object assemble(Serializable cached, Object owner)
        throws HibernateException {
    return null;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
 */
public Object deepCopy(Object value) throws HibernateException {
    return null;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
 */
public Serializable disassemble(Object value) throws HibernateException {
    return null;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object)
 */
public boolean equals(Object x, Object y) throws HibernateException {
    if (x == y) return true;
    if (x == null) return false;
    return x.equals(y);
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
 */
public int hashCode(Object x) throws HibernateException {
    return x == null ? 0 : x.hashCode();
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#isMutable()
 */
public boolean isMutable() {
    return false;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
 */
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
        throws HibernateException, SQLException {
    final long value = rs.getLong(names[0]);
    if (rs.wasNull()) {
        return new Long(Long.MIN_VALUE);
    }
    return new Long(value);
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
 */
public void nullSafeSet(PreparedStatement st, Object value, int index)
        throws HibernateException, SQLException {
    Long l = (Long) value;
    if (l == null || l.longValue() == Long.MIN_VALUE) {
        st.setNull(index, Types.NUMERIC);
    }
    else {
        st.setLong(index, l.longValue());
    }
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
 */
public Object replace(Object original, Object target, Object owner)
        throws HibernateException {
    return original;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#returnedClass()
 */
public Class returnedClass() {
    return Long.class;
}

/* (non-Javadoc)
 * @see org.hibernate.usertype.UserType#sqlTypes()
 */
public int[] sqlTypes() {
    final int[] args = { Types.NUMERIC };
    return args;
}

}

}

回答by Kevin Crowell

It seems that the column that is not nullable should be your primary key. No parts of a composite key should ever be nullable.

似乎不可为空的列应该是您的主键。复合键的任何部分都不应该可以为空。

You will need to take the nullable properties and place them outside of your primary/composite key.

您需要获取可为空的属性并将它们放在主键/复合键之外。

Also, this looks like a duplicate of Hibernate mapping a composite key with null valueswhich came up as #3 when I googled "null composite key".

此外,这看起来像是Hibernate的副本映射一个具有空值的复合键,当我在 google 上搜索“空复合键”时,该复合键出现在 #3 中。