2012-05-23 65 views
4

创建外键复合主键这是一个情况下,我想在我的播放项目表示:无法在播放2.0

table clients { 
    client_id (pk), 
    description 
} 

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

在“项目”表我想有一个复合主键这将包含组合的client_id和item_id。我已阅读JPA文档以及该主题上的许多帖子,但所有内容都一次又一次地失败。这是我尝试过的许多版本之一 - 最接近JPA文档。在COM错误读取注解 models.ItemsPK :

@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) {... 
} 

上面的代码(以及其他许多不同的设置)游戏推出时会产生以下错误:

了java.lang.RuntimeException。 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]

我不知道我的代码可能有什么问题。我开始认为这是一个PLAY错误。有任何想法吗?

+0

你有一个坚实的理由坚持复合PK?即使您设法处理这个问题,您也可能因此面临其他几个问题。为什么不在item表中添加一个额外的列(比如items_id),并在(client_id,item_id)上添加一个唯一索引。 (我想item_id是指物品表,就像client_id引用客户表一样)。 – bpgergo

+0

@bpgergo谢谢你的回答。你的解决方案是可以接受的,但我宁愿避免额外的列和索引。令我惊讶的是,这样一个简单的案例需要解决。如果几天内没有解决方案,我会重新考虑。至于item_id,目前它并没有引用任何其他表,但将来可能会改变。 – Grzywa

+1

标签:hibernate **在这里不正确。没有Hibernate也没有JPA – ses

回答

0

Cześć,

这不是一个答案,而是建议。你能告诉我在你的情况下使用复合PK的主要目标是什么?你的这两款车型将是reaaaaly体积小,易于与Ebean ORM

型号/ 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; 
} 

型号/ 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; 
} 

,这一切。它给你你需要的除了复合PK

+0

在这个系统中,每个item_id应该只在一个client_id内唯一。换句话说,两个不同的客户可以拥有相同ID的项目,但是一个客户不能有两个相同的item_id。 Item_id是用户定义的值。每个用户都可以拥有自己的一套物品。在这方面你的回答并不能解决我的问题。 – Grzywa

+0

Yhm,只是普通的@ManyToMany关系,当然Ebean会为这个+创建'ItemClient'表,您必须确保在保存新关系之前关系不存在,但我仍然认为这是更简单和更便宜的解决方案。恕我直言 – biesior

0

根据我的经验,您无法在EmbeddedId中使用GeneratedValue,因此必须分配组合键中的值。请参阅下面的摘录。

对于简单主键,只需要支持使用GeneratedValue注释 。衍生主键不支持GeneratedValue 注释的使用。

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

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

我建议不使用复合密钥对这个作为itemId将是产生唯一的标识符就足够了。

0

我认为你还没有禁用Ebean。 Ebean是Play 2的默认ORM。如果您想使用JPA,则必须禁用Ebean。

所以在你的构建。斯卡拉,补充一点:

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

而在你application.conf编辑这一行:

ebean.default="models.*" 
+2

你可以使用ebean和JPA批注,所以没有理由禁用ebean。 – stian