I have a below mapping
@Entity
@Table(name = "auctions")
public class Auction{
.
.
@OneToMany(cascade = CascadeType.ALL, mappedBy = "auction")
private List<AuctionParamValue> auctionParamValueList;
.
.
}
@Entity
@Table(name = "auction_param_values")
public class AuctionParamValue {
@EmbeddedId
protected AuctionParamValuePK auctionParamValuePK;
@JoinColumn(name = "auction_param_id", referencedColumnName = "auction_param_id",updatable=false,insertable=false)
@ManyToOne @MapsId("auctionParamId")
private AuctionParam auctionParam;
@JoinColumn(name = "auction_id", referencedColumnName = "auction_id",updatable=false,insertable=false)
@ManyToOne @MapsId("auctionId")
private Auction auction;
}
@Embeddable
public class AuctionParamValuePK {
@Id
@Basic(optional = false)
@Column(name = "auction_id")
@Nullable
private Long auctionId = null;
@Id
@Basic(optional = false)
@Column(name = "auction_param_id")
@Nullable
private Long auctionParamId = null;
}
@Entity
@Table(name = "auction_params")
public class AuctionParam {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "auctionParam")
private List<AuctionTypeParam> auctionTypeParamList;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "auctionParam")
private List<AuctionParamValue> auctionParamValueList;
}
}
When I try to persist auction (I am manually setting the auctionParamId and expecting the auctionId to be automaticlly set (may be the last inserted id) )
but I am getting below error, I am not sure why the auctionId in the query is going as 0 instead of latest id in the auction.(I am using eclipselink jpa provider)
Internal Exception: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`portaldemo`.`auction_param_values`, CONSTRAINT `auction_param_values_auction_id_fk` FOREIGN KEY (`auction_id`) REFERENCES `auctions` (`auction_id`))
Error Code: 1452
Call: INSERT INTO auction_param_values (auction_param_val, create_ts, last_updt_ts, auction_param_id, auction_id) VALUES (?, ?, ?, ?, ?)
bind => [2011-02-12 04:00:00, 2011-01-27 12:02:00.28, 2011-01-27 12:17:43.25, 2, 0]
Query: InsertObjectQuery(com.eaportal.domain.AuctionParamValue[auctionParamValuePK=com.eaportal.domain.AuctionParamValuePK[auctionId=0, auctionParamId=2]])
Here the [auctionId=0 is always comming as 0 and not the last inserted id :(
What is theproblem with this mapping ?
An @GeneratedValue will only set the value of the attribute it is annotated on, if you have other attributes in other classes that reference the id you are responsible for setting these.
i.e. you would need to first persist and flush the Auction, and then create the AuctionParamValue using its generate Id.
Or, if you used TABLE or SEQUENCE id generation then you would just need to call persist, and not the flush. In general I would never recommend IDENTITY sequencing as its values cannot be preallocated.
But really you should not have the duplicate fields as all. Remove the @EmbeddedId auctionParamValuePK entirely and just add @Id to the two @ManyToOnes, and use an @IdClass instead. This will make things much simplier and will just work, even with IDENTITY id generation.
You could also instead remove the insertable/updateable=false on the two @ManyToOne mappings and instead put them on the @EmbeddedId attributes, this will have the foreign key written from the relationships, but your object will still be corrupt in memory.
See, http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_and_ManyToOne_Relationships
You could try two things:
I don't know if this fix the problem, but I am sure that you need to do at least one of them to get it working.