将主键作为外键映射到另一个表

时间:2013-11-24 21:00:08

标签: java mysql jpa playframework-2.0 ebean

关于外键关系及其JPA对应关系我有问题。

在下表中。 means_of_transport是一个连续编号的表。其他表具有较少的条目,其主键作为外键到means_of_transport的主键映射。可悲的是,我无法改变数据模型。

means_of_transport

CREATE TABLE means_of_transport (
    id INT PRIMARY KEY NOT NULL,
    max_capacity INT
);

ocean_ship

CREATE TABLE ocean_ship (
    means_of_transport_id INT PRIMARY KEY NOT NULL,
    name VARCHAR(45) NOT NULL,
    FOREIGN KEY ( means_of_transport_id ) REFERENCES means_of_transport ( id )
);
CREATE INDEX fk_ship_means_of_transport1_idx ON ocean_ship ( means_of_transport_id );

除了ocean_ship之外,还有更多的表具有相同的键结构,但其他字段。

MeansOfTransport.java

@Entity
@Table(name = "means_of_transport")
public class MeansOfTransport extends Model {
    @Id
    public Integer id;
    public Integer maxCapacity;
}

OceanShip.java

@Entity
@Table(name = "ocean_ship")
public class OceanShip extends Model {
    @Id
    @OneToOne
    @JoinColumn(table = "means_of_transport", referencedColumnName = "id")
    public MeansOfTransport meansOfTransport;

    public String name;
}

现在,每当我尝试在另一个JPA类中使用OceanShip作为字段时,我都会收到此错误:Error reading annotations for models.Classname

我错过了一些注释吗?

修改

使用示例:

@ManyToOne
@Column(name = "ocean_ship")
public OceanShip oceanShip;

完整堆栈跟踪:

play.api.UnexpectedException: Unexpected exception[RuntimeException: Error reading annotations for models.ContainerOrder]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:150) ~[play_2.10.jar:2.1.5]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:114) ~[play_2.10.jar:2.1.5]
        at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:114) ~[play_2.10.jar:2.1.5]
        at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:112) ~[play_2.10.jar:2.1.5]
        at scala.util.Either$RightProjection.flatMap(Either.scala:523) ~[scala-library.jar:na]
Caused by: java.lang.RuntimeException: Error reading annotations for models.ContainerOrder
        at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:54) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1034) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEntityDeploymentAssociations(BeanDescriptorManager.java:565) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.deploy(BeanDescriptorManager.java:252) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.core.InternalConfiguration.<init>(InternalConfiguration.java:124) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:210) ~[avaje-ebeanorm-server.jar:na]
Caused by: java.lang.NullPointerException: null
        at com.avaje.ebeaninternal.server.deploy.BeanTable.createJoinColumn(BeanTable.java:94) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.readAssocOne(AnnotationAssocOnes.java:145) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.parse.AnnotationAssocOnes.parse(AnnotationAssocOnes.java:54) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.parse.ReadAnnotations.readAssociations(ReadAnnotations.java:45) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readDeployAssociations(BeanDescriptorManager.java:1034) ~[avaje-ebeanorm-server.jar:na]
        at com.avaje.ebeaninternal.server.deploy.BeanDescriptorManager.readEntityDeploymentAssociations(BeanDescriptorManager.java:565) ~[avaje-ebeanorm-server.jar:na]

3 个答案:

答案 0 :(得分:3)

我认为你的数据库模型在概念上是不对的。

下面应该是这样的。

ocean_ship_id是ocean_ship表的PK。 来自ocean_ship的means_of_transport_id 只是一个FK到“基地”表means_of_transport。

所以我会说你的数据库模型正确, 然后担心JPA映射。

CREATE TABLE ocean_ship (
    ocean_ship_id INT PRIMARY KEY NOT NULL,
    means_of_transport_id INT NOT NULL,
    name VARCHAR(45) NOT NULL,
    FOREIGN KEY ( means_of_transport_id ) REFERENCES means_of_transport ( id )
);

答案 1 :(得分:1)

请参阅@PrimaryKeyJoinColumn以及此主题中提供的想法。

Shared primary key with JPA @MapsId annotation

可能有帮助吗?

答案 2 :(得分:1)

出现错误消息,因为某些注释错误。

我将OceanShip的主键从MeansOfTransport更改为Integer,现在要小心我进入那里。这是我必须支付的价格。

此外,我更改了我在此

中使用OceanShip的注释
@ManyToOne
@Column(name = "ocean_ship")
public OceanShip oceanShip;

到这个

@ManyToOne
@JoinColumn(name = "ocean_ship", referencedColumnName = "means_of_transport_id")
public OceanShip oceanCarrierShip;