Reputation: 378
I'll try to put it simple. I have a table with a composite primary key composed of two Long attributes, wrapped by an @IdClass annotated class.
@IdClass Attributes:
public class MyPK implements Serializable {
private Long id;
private Long version;
} // + hashCode, constructors, etc.
What I am failing to do:
To INSERT a new record while keeping the value of "id" and incrementing "version".
Example scenario:
Existing record - {id:1, version:1}
Desired new record (NOT UPDATED, talking about a new one) - {id:1, version:2}
What I have done:
At first I attempted incrementing version while keeping the sequence generator I was using. Below is how the id was annotated:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSequence")
@SequenceGenerator(name = "idSequence", sequenceName = "SQ_ID", allocationSize = 1)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;
The above resulted in the provided id being overriden with sequence's nextVal, so no deal for me.
So my 2nd approach was to play around inheritance and internal Hibernate classes, something I always try to avoid:
public class MySequenceStyleIdGenerator extends SequenceStyleGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object){
Serializable id = session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null && ((MyPK)id).getId() != null
? id : super.generate(session, object);
}
}
And making changes to the entity class as needed:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "providedIdOrSequence")
@GenericGenerator(
name="providedIdOrSequence",
strategy="{package}.MySequenceStyleIdGenerator",
parameters = @org.hibernate.annotations.Parameter(
name = "sequence_name",
value = "SQ_ID"
)
)
@Column(name = "ID", nullable = false, updatable = false)
private Long id;
This, on the other hand, returns nextVal into id ONLY when it is null, which is what I wanted. The problem then shifts to something darker and deeper within the library, as if it tries to assign the id (Long) to the PK type itself instead of its Long attribute:
java.lang.IllegalArgumentException: Can not set java.lang.Long field {package}.CotacaoPK.idCotacao to {package}.CotacaoPK
If both PK attributes (id and version) are kept unchanged, then I get no error.
Any ideas? I've put a reasonable number of hours into it already... thanks.
Upvotes: 0
Views: 859
Reputation: 378
Problem solved!
The problem was in my SequenceStyleGenerator implementation. super.generate(...) returns a Long, but I was returning id as the wrapping MyPK object. So the solution would be:
public class MySequenceStyleIdGenerator extends SequenceStyleGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object){
Serializable id = session.getEntityPersister(null, object)
.getClassMetadata().getIdentifier(object, session);
return id != null && ((MyPK)id).getId() != null
? ((MyPK)id).getId() : super.generate(session, object);
}
}
Upvotes: 0