JPA @MapsId插入错误的列名

Ria*_*ian 6 java hibernate jpa

尽管在网上播放了所有的例子,但我无法让@MapsId工作.

这是我的设置:

pom.xml中:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>4.3.5.Final</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.31</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

DDL脚本:

CREATE TABLE Subscription (
    id bigint not null primary key auto_increment,
    active boolean not null,
    maxNumUsers int not null
)ENGINE=InnoDB;

CREATE TABLE t.Project (
    name varchar(32) not null,
    subscriptionId bigint not null
)ENGINE=InnoDB;

ALTER TABLE t.Project ADD CONSTRAINT `projectPK` PRIMARY KEY (name, subscriptionId);
ALTER TABLE t.Project ADD CONSTRAINT `projectSubscriptionFK` FOREIGN KEY (subscriptionId) REFERENCES t.Subscription(id);
Run Code Online (Sandbox Code Playgroud)

ProjectId.java:

@Embeddable
public class ProjectId implements Serializable {
    private Long subscriptionId;
    private String name;
Run Code Online (Sandbox Code Playgroud)

Project.java:

@Entity
@Table(schema = "t")
public class Project {
    @EmbeddedId
    private ProjectId id;

    @ManyToOne
    @MapsId("subscriptionId")
    //@JoinColumn(name = "subscriptionId", referencedColumnName = "id", insertable = false, updatable = false)
    private Subscription subscription;
Run Code Online (Sandbox Code Playgroud)

Subscription.java:

@Entity
@Table(schema = "t")
public class Subscription {

    @OneToMany(mappedBy = "subscription", cascade = CascadeType.ALL)
    private Map<ProjectId, Project> projects = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

当我执行插入时,会发生以下错误:

Hibernate:插入到t.Project(name,subscription_id)值(?,?)2014-07-20 11:06:59,193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL错误:1054,SQLState:42S22 2014- 07-20 11:06:59,193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - '字段列表'中的未知列'subscription_id'

...

... 94更多引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:sun.reflect.NativeConstructorAccessorImpl.newInstance中sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)的'field list'中的未知列'subscription_id' (NativeConstructorAccessorImpl.java:57)位于com.mysql.jdbc.Util.handleNewInstance的java.lang.reflect.Constructor.newInstance(Constructor.java:526)中的sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)( Util.java:408)com.mysql.jdbc.Util.getInstance(Util.java:383)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)at com.mysql.jdbc.MysqlIO.checkErrorPacket (MysqlIO.java:4226)com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158)位于com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)com.mysql.jdbc.MysqlIO的com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158). sqlQueryDirect(MysqlIO.java:2776)位于com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840)的com.mysql.jdbc.PreparedStatement.executeIntern al(PreparedStatement.java:2082)位于com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2334)的com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2262)com.mysql.jdbc.PreparedStatement .executeUpdate(PreparedStatement.java:2246)org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)... 114 more

如果我取消了@JoinColumnProject.subscription和重新部署我得到这个错误:

... 21更多引起:org.hibernate.MappingException:集合映射中的重复列:t.Subscription.projects列:subscriptionId

我也尝试删除了@MapsId,我仍然得到重复的列错误.

我很难过如何解决这个问题.任何建议,将不胜感激.

谢谢


更新:如果我使Subscription.projects成为列表而不是地图,我将JoinColumn添加到project.subscription它可以工作.但是,如果我将subscription.projects更改回地图,我会再次开始获取org.hibernate.MappingException:Repeated列.显然我真的想使用地图所以我会继续挖掘.

Ria*_*ian 6

好的,所以问题是我需要将 @MapKey 添加到 subscription.projects 否则当我添加 @JoinColumn 时它会抱怨“org.hibernate.MappingException:Repeated column”

谢谢你的建议

这是最终的代码:

@Embeddable
public class ProjectId implements Serializable {
    private Long subscriptionId;
    private String name;

@Entity
@Table(schema = "t")
public class Project {
    @EmbeddedId
    private ProjectId id;

    @ManyToOne
    @MapsId("subscriptionId")
    @JoinColumn(name = "subscriptionId", referencedColumnName = "id", insertable = false, updatable = false)
    private Subscription subscription;


@Entity
@Table(schema = "t")
public class Subscription {

    @OneToMany(mappedBy = "subscription", cascade = CascadeType.ALL)
    @MapKey(name = "id")
    private Map<ProjectId, Project> projects = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 5

使用mapsId批注时,您指定关系共享并控制由ID映射映射的字段,因此关系映射中的字段将覆盖ID映射中的字段。这意味着除非您指定注释掉的联接列,否则JPA将使用默认的subscription_id:

@JoinColumn(name = "subscriptionId", referencedColumnName = "id")
Run Code Online (Sandbox Code Playgroud)