Hi, I have a problem with a composite key.
I just switched form synthetic key to composite key. The key contains the properties (name, type, year, comment).
Code:
@Entity
public class Laendermodell implements Comparable<Laendermodell> {
@Version
@Column(name = "VERSION_OPTLOCK")
@SuppressWarnings("unused")
private long version;
@Enumerated(value = EnumType.STRING)
@Id
private KnownCountries name;
@Id
private Integer year;
@Enumerated(value = EnumType.STRING)
@Id
private Variations type;
@Id
@Lob
private String comment;
.
.
.
some other properties
This produces the following error:
Quote:
Could not execute JDBC batch update
Batch-Eintrag 0 insert into Laendermodell (unternehmensmodell_id, VERSION_OPTLOCK, waehrungssymbol, wechselkurs, comment) values (475, 0, €, 1000, ) wurde abgebrochen.
ERROR: null value in column "year" violates not-null constraint
(-- wurde abgebrochen. == aborted --)
I had set year to int before. Also year is 2008 by default. So it's most unlikely that the message is correct. I think hibernate doesn't recognize that comment is part of the key.
Also the rest of the class anotations are correct, because before I used an synthetic id, which worked fine. (Had droped and recreated the db in the meantime) Now I have switched to a natarual id, which is causing this problem.
What's wrong?
Is it possible to do that without @IdClass ?
Thanks a lot in advance.
Greetings Michael
PS: Also tried it without @Lob and @Enumerated annotation and l changed year back to int, but haven't changed the problem yet. int can't be possible null, so the error-message must be wrong!
PPS:
With:
Code:
@Entity
@IdClass(LaendermodellPK.class)
public class Laendermodell implements Comparable<Laendermodell> {
and
Code:
Embeddable
public class LaendermodellPK implements Serializable {
@Enumerated(value = EnumType.STRING)
private KnownCountries name;
@Basic
private int year;
@Enumerated(value = EnumType.STRING)
private Variations type;
@Lob
private String comment;
private LaendermodellPK() {
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final LaendermodellPK other = (LaendermodellPK) obj;
if (this.comment == null) {
if (other.comment != null) {
return false;
}
}
else
if (!this.comment.equals(other.comment)) {
return false;
}
if (this.name == null) {
if (other.name != null) {
return false;
}
}
else
if (!this.name.equals(other.name)) {
return false;
}
if (this.type == null) {
if (other.type != null) {
return false;
}
}
else
if (!this.type.equals(other.type)) {
return false;
}
if (this.year != other.year) {
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.comment == null) ? 0 : this.comment.hashCode());
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
result = prime * result + this.year;
return result;
}
}
it works. So it seems that only one @Id is allowed, as long as @IdClass is missing.
By I still have some questions.
Is there any possibility do this without @IdClass(LaendermodellPK.class) ?
Why do I have to specify a own (public) class?
Why do I have to tag the class with "implements Serializable"?
Do I have to implement
Quote:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;
? At least it works without.
Thanks a lot in advance.
Greetings Michael