我有一个包含许多数据库实体的大型Java EE项目,并且JPA约束检查给我带来了很多麻烦!
首先,我有许多具有多种依赖关系的实体(OneToOne,OneToMany)。整个项目用于自动分析和计算OSS存储库中源代码的指标。 (se.uom.gr/seagle)。
例如,有一个实体项目和一个实体Project_Timeline,用于保存历史分析信息。
这是Project实体类
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 255)
@Column(name = "name", unique = true)
private String name;
/**
* A remote URL from where this project is cloned.
* <p>
*/
@Size(max = 2048)
@Column(name = "remoteRepoPath", unique = true)
private String remoteRepoPath;
/**
* The metrics that should be calculated on the next execution.
* <p>
*/
@ManyToMany(mappedBy = "registeredProjects")
private Collection<Metric> registeredMetrics;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "project", orphanRemoval = true)
private Collection<Version> versions;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "project")
private ProjectInfo projectInfo;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "project", orphanRemoval = true)
private Collection<ProjectTimeline> timeLines;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "project", orphanRemoval = true)
private Collection<ProjectMetric> projectMetrics;
这是Project_TimeLine实体类
public class ProjectTimeline implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id")
private Integer id;
@Column(name = "timestamp")
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
@JoinColumn(name = "project_id", referencedColumnName = "id")
@ManyToOne(optional = false)
private Project project;
如果我正确理解了JPA指南,那么这些实体的正确创建是:
Project p = new Project();
project.setName("some-java-oss");
project.setURL("http:////bla bla bla");
ProjectTimeline pi = new ProjectTimeline();
pi.setProject(p);
p.setProjectTimeline(pi);
entityManager.persist(p);
entityManager.persist(pi);
所以我只对此,并期望JPA处理主键并成功加入。
BUT
JPA和Glassfish一直给我以下错误:
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'id' cannot be null
Error Code: 1048
Call: INSERT INTO project_timeline (id, timestamp, action_id, project_id) VALUES (?, ?, ?, ?)
bind => [4 parameters bound]
Query: InsertObjectQuery(gr.uom.java.seagle.db.persistence.v2.ProjectTimeline[ id=null ])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
... 266 more
Caused by:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'id' cannot be null
... 297 more
完整错误堆栈跟踪在这里:
http://java.uom.gr/~chaikalis/documents/full_error_stacktrace.txt