美好的一天,请告知我为什么会遇到异常情况。我是EclipseLink初学者,我使用的是jdk1.7.0_05,MySQL服务器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
表格许可证如下所示:
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;
表活动:
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;
表格版本:
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;
我在NetBeans中使用New->数据库中的实体类生成的类看起来像这样:
班级版本:
@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;
...
我在执行以下代码时遇到异常:
...
ActivityPK apk = new ActivityPK();
apk.setLicenseId(activity.getLicense().getId());
activity.setActivityPK(apk);
em.persist(activity);
em.flush(); <- Here the exception is thrown
...
我怀疑是因为活动尚未分配ID而VerionPK使用此ID。我对吗?保留此类数据的正确方法是什么?在将版本集合设置为null的持久化活动后,我是否应该单独保留版本集合? 提前谢谢了。 Vojtech
答案 0 :(得分:1)
查看JPA 2.0的派生ID。您可以将关系标记为ID,或者使用映射Id指定id字段的关系,而不必自己手动设置值。这会在创建新树时处理问题,并且根实体使用顺序 - 在持久保存根之前,子项无法使用id作为外键。
否则,需要持久保存和刷新根实体,以便分配Id。在这种情况下,Activity实体需要主键值才能尝试并保留引用它的新Version对象,因为您必须手动设置所有version.versionpk值。