Search code examples
jpaeclipselink

Creating table form JPA Entity fails


I have set-up a completely new JPA Project in Eclipse (Kepler)...after I ran into issues in an existing project.

I intend to write a JpaEntity and let Eclipse (or JPA respectively) create the respective table in the database but this fails and I can't figure out the reason. Eclipse tells me Table "myentrances" cannot be resolved. Of course...it doesn't exist by now. ...it shall be created yet.

Here's my JpaEntity:

@Entity
@Table(name="myentrances")
@NamedQuery(name="MyEntrance.findAll", query="SELECT e FROM MyEntrance e")
@TableGenerator(name = "myentrances")
@Access(PROPERTY)
public class MyEntrance implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int entranceId;

    @OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.EAGER, orphanRemoval = true)
    @PrimaryKeyJoinColumn
    private Address address;

    @Column(nullable=false)
    private double maxHeight;

    @Column(nullable=false)
    private String maxHeightUom;

    private static final long serialVersionUID = 1L;

    public MyEntrance() {
        super();
    } 

    public int getEntranceId() {
        return this.entranceId;
    }

    public void setEntranceId(int entranceId) {
        this.entranceId = entranceId;
    }

    public Address getAddress() {
        return this.address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public double getMaxHeight() {
        return this.maxHeight;
    }

    public void setMaxHeight(double maxHeight) {
        this.maxHeight = maxHeight;
    }

    public String getMaxHeightUom() {
        return this.maxHeightUom;
    }

    public void setMaxHeightUom(String maxHeightUom) {
        this.maxHeightUom = maxHeightUom;
    }
}

Here's my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="JpaTest" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>com.tsystems.ikt.model.Address</class>
    <class>com.tsystems.ikt.model.MyEntrance</class>
    <properties>
        <property name="eclipselink.ddl-generation" value="create-tables"/>
        <property name="eclipselink.ddl-generation.output-mode" value="database"/>
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/myDb"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
    </properties>
</persistence-unit>

Here's the exception I get:

[EL Config]: metadata: The element [method getAddress] is being defaulted to a one to one mapping.
[EL Config]: metadata: The target entity (reference) class for the one to one mapping element [method getAddress] is being defaulted to: class com.tsystems.ikt.model.Address.
[EL Config]: metadata: The access type for the persistent class [class com.tsystems.ikt.model.Address] is set to [FIELD].
[EL Config]: metadata: The access type for the persistent class [class com.tsystems.ikt.model.MaiEntrance] is set to [FIELD].

[EL Config]: metadata: The alias name for the entity class [class com.tsystems.ikt.model.MyEntrance] is being defaulted to: MyEntrance.
[EL Config]: metadata: The column name for element [getEntranceId] is being defaulted to: ENTRANCEID.
[EL Config]: metadata: The column name for element [getMaxHeightUom] is being defaulted to: MAXHEIGHTUOM.
[EL Config]: metadata: The column name for element [getMaxHeight] is being defaulted to: MAXHEIGHT.
Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: org.eclipse.persistence.dynamic.DynamicClassLoader@580760d7
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JpaTest] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.tsystems.ikt.model.MyEntrance] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:127)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:177)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.buildEntityManagerFactory(Main.java:94)
at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.execute(Main.java:80)
at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.main(Main.java:68)
Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JpaTest] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.tsystems.ikt.model.MyEntrance] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:1954)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1945)
at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:98)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:96)
... 5 more
Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [JpaTest] failed.
Internal Exception: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.tsystems.ikt.model.MyEntrance] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:230)
... 9 more
Caused by: Exception [EclipseLink-7161] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class com.tsystems.ikt.model.MyEntrance] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.ValidationException.noPrimaryKeyAnnotationsFound(ValidationException.java:1422)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.validatePrimaryKey(EntityAccessor.java:1536)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1243)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:697)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1793)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:576)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:585)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1869)
... 7 more   

I am only using field access (in Address as well).

I am using Eclipselink 2.5.1.

By the way: Isn't it possible to create a table for just a single newly created JpaEntity? Do I ever have to chose MyProject-->JPA Tools-->Generate TableS from EntitieS? This seems to create ALL existing tables as well, does it? What if I have already created a bunch of tables and now just want to add one further table based by a newly created JpaEntity?


Solution

  • The default access mode for entities in JPA is AccessType.FIELD.

    You have overwritten it by declaring @Access(PROPERTY) for the entity therefore @Id annotation is unnoticed by the persistence provider while processing metadata. Try to remove @Access(PROPERTY) annotation to solve the problem.

    What if I have already created a bunch of tables and now just want to add one further table based by a newly created JpaEntity?

    It depends from a scenario:

    • if dropping existing tables is forbidden for any reason (i.e. in case of legacy database): leave create-tables in persistence.xml so that the provider creates the table based on a new entity (i.e. MyEnterance); for already existing table you may use DROP TABLE myentrances later on to remove the corresponding table and recreate it automatically during the next start up - the provider will take care of recreating the entity from scratch
    • if dropping existing tables is allowed: replace create-tables with drop-and-create-tables in persistence.xml - the provider will take care of recreating the whole entity model from scratch