Can't create composite primary key with foreign key in PLAY 2.0

对着背影说爱祢 提交于 2019-12-22 08:55:13

问题


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?


回答1:


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




回答2:


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.




回答3:


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.*"


来源:https://stackoverflow.com/questions/10723465/cant-create-composite-primary-key-with-foreign-key-in-play-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!