2009-03-23 9 views
2

Ich verwende Hibernate JPA Impl, um einige Tabellen zu modellieren. Ich habe Probleme mit einer Tabelle abbildet, dass:Jpa Composite-Schlüssel Nullwert Spalten

  • Hat kein Primärschlüssel
  • hat einen eindeutigen Index auf 4 Säulen, von denen 3

nullable sein kann, habe ich versucht, es zu hacken und definieren der Index als eine zusammengesetzte ID, aber da einige Spalten Nullable sind, funktioniert dies nicht richtig. Ist das mit JPA/Hibernate möglich?

Dank

Antwort

1

Eine Arbeit ist um ... Sie sollten Ihre eigene UserType-Implementierung implementieren und behandelt den Nullwert, um ein repräsentatives Objekt dafür zurückzugeben.

Schau mein Beispiel. Das Feld ist ein Nullable-numerisch, so meine Implementierung ist:

Sieht aus wie in HBM-Datei:

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

... In 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; 
} 

}

1

Es scheint, dass die Spalte, die keine Nullwerte enthalten ist Ihr Primärschlüssel sein sollte. Teile eines zusammengesetzten Schlüssels sollten niemals nullfähig sein.

Sie müssen die Nullable-Eigenschaften übernehmen und sie außerhalb Ihres primären/zusammengesetzten Schlüssels platzieren.

Auch das sieht aus wie ein Duplikat von Hibernate mapping a composite key with null values, die als # 3 kam, wenn ich "Null Composite Key" googelte.

+0

Beachten Sie, dass ich die nicht NULL-fähige Spalte nicht als PK angeben kann, da die Spalte selbst nicht eindeutig ist, sondern nur die Kombination von Spalten. Ich weiß, das ist ein schlechtes Design, aber ich habe keine Kontrolle über das DB-Modell. –

+1

Da die Kombination der Spalten immer eindeutig ist (ob es Nullwerte gibt oder nicht) und die Anzahl der Spalten nie null ist (wegen der Spalte, die keine Nullwerte enthalten kann), dachte ich, dass dies möglich wäre. –

+0

Datenbanken sollen dies nicht erlauben, aber einige tun. Leider haben Sie keine Kontrolle über das Datenbankschema. Können Sie mit den Leuten sprechen, die das Schema kontrollieren? Sorry, aber ich kenne keine Workaround/Hack, um dies mit Hibernate arbeiten zu lassen. –