문제

This is a situation I want to represent in my PLAY project:

table clients {
     client_id (pk),
     description
}

table items {
     client_id (fk, pk),
     item_id (pk)
}

In the 'items' table I want to have a composite primary key that will consist of combined client_id and item_id. I have read JPA documentation as well as many posts on the topic but everything fails again and again. This is one of many versions I have tried - closest to the JPA documentation.

@Entity
@Table(name = "items")
public class Items extends Model {
    ItemsPK primaryKey;

    public Items() {
    }

    @EmbeddedId
    public ItemsPK getPrimaryKey() {
        return primaryKey;
    }

    public void setPrimaryKey(ItemsPK pk) {
        primaryKey = pk;
    }
}

@Embeddable
public class ItemsPK implements Serializable {
    private long itemId;
    private Client client;

    public ItemsPK() {
    }

    @Column(name = "item_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getItemId() {
        return itemId;
    }

    public void setItemId(long itemId) {
        this.itemId = itemId;
    }

    @ManyToOne
    @JoinColumn(name = "client_id", nullable = false)
    public Client getClient() {
        return client;
    }

    public void setClient(Client client) {
        this.client = client;
    }

    //public int hashCode() {...
    //public boolean equals(Object obj) {...
}

The above code (as well as many other different setups) produce following error during play launch:

java.lang.RuntimeException: Error reading annotations for models.ItemsPK at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:73) ~[ebean.jar:na] at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1100) ~[ebean.jar:na]

I don't have a clue what might be wrong with my code. I'm starting to think that it is a PLAY bug. Any ideas?

도움이 되었습니까?

해결책

Cześć,

This not an answer, rather suggestion. Can you tell me what is main goal of using composite PK in your case? Your both models would be reaaaaly small and easy with Ebean ORM

models/Client.java

package models;

import play.db.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Client extends Model {
    @Id
    public Long id;
    public String description;
}

models/Item.java

package models;

import play.db.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Item extends Model {
    @Id
    public Long id;

    @ManyToOne
    public Client client;
}

and that's all. It gives you what you need except the composite PK

다른 팁

In my experience, you are not able to use GeneratedValue inside an EmbeddedId, the values in a composite key must be assigned. See excerpt below.

The use of the GeneratedValue annotation is only required to be supported for simple primary keys. Use of the GeneratedValue annotation is not supported for derived primary keys.

http://docs.oracle.com/javaee/6/api/javax/persistence/GeneratedValue.html

http://www.objectdb.com/api/java/jpa/GeneratedValue

I would recommend not using a composite key for this as itemId would be sufficient in generating a unique identifier.

I think that you haven't disabled Ebean. Ebean is the default ORM for Play 2. If you want to use JPA you have to disable Ebean.

So in your Build.scala, add this:

val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
    ebeanEnabled := false
)

And in your application.conf edit this line:

ebean.default="models.*"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top