Good day, please advise why am I getting following exception. I’m EclipseLink beginner, I’m using jdk1.7.0_05, MySQL server 5.5.25a.
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`stats`.`version`, CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Error Code: 1452
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`stats`.`version`, CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Error Code: 1452
Call: INSERT INTO version (version, activity_id, product, activity_license_id) VALUES (?, ?, ?, ?)
bind => [4 parameters bound]
Query: InsertObjectQuery(cz.ryvo.stats.database.Version[ versionPK=cz.ryvo.stats.database.VersionPK[ product=AP, activityId=0, activityLicenseId=0 ] ])
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:786)
at cz.audatex.audaupdateloader.DatabaseHelper.registerActivity(DatabaseHelper.java:104)
... 3 more
Table License looks like this:
CREATE TABLE `license` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`license` varchar(20) NOT NULL,
`organisation_id` int(11) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `license_UNIQUE` (`license`),
KEY `fk_license_user1` (`user_id`),
KEY `fk_license_organisation1` (`organisation_id`),
CONSTRAINT `fk_license_organisation1` FOREIGN KEY (`organisation_id`) REFERENCES `organisation` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_license_user1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
Table Activity:
CREATE TABLE `activity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`license_id` int(11) NOT NULL,
`time` datetime NOT NULL,
`type` char(1) NOT NULL,
`result` int(1) DEFAULT NULL,
PRIMARY KEY (`id`,`license_id`),
UNIQUE KEY `activity_UQ01` (`license_id`,`time`,`type`),
KEY `fk_activity_license1` (`license_id`),
CONSTRAINT `fk_activity_license1` FOREIGN KEY (`license_id`) REFERENCES `license` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
And table Versions:
CREATE TABLE `version` (
`product` varchar(45) NOT NULL,
`activity_id` int(11) NOT NULL,
`activity_license_id` int(11) NOT NULL,
`version` varchar(45) DEFAULT NULL,
PRIMARY KEY (`product`,`activity_id`,`activity_license_id`),
KEY `fk_version_activity1` (`activity_id`,`activity_license_id`),
CONSTRAINT `fk_version_activity1` FOREIGN KEY (`activity_id`, `activity_license_id`) REFERENCES `activity` (`id`, `license_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
My classes I generated in NetBeans using New->Entity Classes from database look like this:
Class Version:
@Entity
@Table(name = "version")
@XmlRootElement
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected VersionPK versionPK;
@Column(name = "version")
private String version;
@JoinColumns({
@JoinColumn(name = "activity_id", referencedColumnName = "id", insertable = false, updatable = false),
@JoinColumn(name = "activity_license_id", referencedColumnName = "license_id", insertable = false, updatable = false)})
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Activity activity;
...
Class VersionPK:
@Embeddable
public class VersionPK implements Serializable {
@Basic(optional = false)
@Column(name = "product")
private String product;
@Basic(optional = false)
@Column(name = "activity_id")
private int activityId;
@Basic(optional = false)
@Column(name = "activity_license_id")
private int activityLicenseId;
...
I’m gettin the exception when I execute following code:
...
ActivityPK apk = new ActivityPK();
apk.setLicenseId(activity.getLicense().getId());
activity.setActivityPK(apk);
em.persist(activity);
em.flush(); <- Here the exception is thrown
...
I suspect it is because activity does not have ID assigned yet and VerionPK uses this ID. Am I right? What is the proper way to persist such data? Should I persist version collection separately after persisting activity with version collection set to null?
Many thanks in advance. Vojtech

Check out JPA 2.0’s derived Ids. You can mark the relationship as the ID, or specify that the relationship the id field using maps Id instead of having to manually set the value yourself. This takes care of the problem when creating a new tree and the root entity uses sequencing – the ids aren’t available to the children to use as foreign keys until the root is persisted.
Otherwise, the root entity needs to be persisted and flushed so that an Id is assigned. In this case, the Activity entity needs primary key values before you can try and persist a new Version object that reference it since you must manually set all the version.versionpk values.