We have generic abstract class GenericDependency and several implementing subclasses.
@MappedSuperclass
public abstract class GenericDependency<P, C> extends DatabaseEntity {
@ManyToOne
@JoinColumn(nullable = false)
private P parent;
@ManyToOne
@JoinColumn(nullable = false)
private C child;
...
}
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "parent_id", "child_id" }))
public class ArtifactArtifactDependency extends GenericDependency<Artifact, Artifact> implements Serializable {
...
}
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames = { "parent_id", "child_id" }))
public class ArtifactReleaseDependency extends GenericDependency<Artifact, Release> implements Serializable {
...
}
In persistence.xml we have them in this order:
<class>org.jboss.buildtracker.database.dao.model.dependency.ArtifactArtifactDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ArtifactDeveloperDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ArtifactLicenseDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ArtifactReleaseDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ProductProjectDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ProjectLicenseDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ProjectSyncInfo</class><class>org.jboss.buildtracker.database.dao.model.dependency.ReleaseDeveloperDependency</class><class>org.jboss.buildtracker.database.dao.model.dependency.ReleaseLicenseDependency</class>
The problem occured when using criteria api:
Root<ArtifactReleaseDependency> d2 = cq.from(ArtifactReleaseDependency.class);
Path<Release> child = d2.<Release>get("child");
Path<Project> project = child.<Project>get("project");
In child there were reference to Artifact instead of Release so it throws exception on the 3rd line as it can't found project attribute on Artifact.
The reason is that when building metamodel, ArtifactArtifactDependency is processed first and it's superclass GenericDependency metamodel is build with attributes child and parent as Artifact. When building metamoded for ArtifactReleaseDependency, the superclass metamodel is reused resulting in wrong thinking that child attribute is Artifact instead of Release.
|