Java JPA@MapsId插入不正确的列名

Java JPA@MapsId插入不正确的列名,java,hibernate,jpa,Java,Hibernate,Jpa,我很难让@MapsId正常工作,尽管我遵循了网络上的所有示例 以下是我的设置: pom.xml: <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.3.5.Final</version> </dependency> &

我很难让@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>
projectd.java:

@Embeddable
public class ProjectId implements Serializable {
    private Long subscriptionId;
    private String name;
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;
Subscription.java:

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

    @OneToMany(mappedBy = "subscription", cascade = CascadeType.ALL)
    private Map<ProjectId, Project> projects = new HashMap<>();
@实体
@表(schema=“t”)
公开课订阅{
@OneToMany(mappedBy=“subscription”,cascade=CascadeType.ALL)
私有映射项目=新HashMap();
执行插入时,会发生以下错误:

Hibernate:在t.Project(名称、订阅id)中插入值(?,) 2014-07-20 11:06:59,193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper-SQL错误:1054, SQLState:42S22 2014-07-20 11:06:59193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper-未知列 “字段列表”中的“订阅id”

…94更多原因是: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:未知 位于的“字段列表”中的“订阅id”列 sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 位于java.lang.reflect.Constructor.newInstance(Constructor.java:526) 位于com.mysql.jdbc.Util.handleNewInstance(Util.java:408) com.mysql.jdbc.Util.getInstance(Util.java:383)位于 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)位于 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.sqlQueryDirect(MysqlIO.java:2776)位于 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840)位于 com.mysql.jdbc.PreparedStatement.executeInternal(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个

如果取消对Project.subscription上的
@JoinColumn
的注释并重新部署,则会出现以下错误:

…21更多原因:org.hibernate.MappingException:重复列 在集合的映射:t.Subscription.projects列中: 订阅ID

我也尝试过删除
@MapsId
,但仍然会出现重复的列错误

我被难住了,不知道该如何解决这个问题。如有任何建议,我将不胜感激

谢谢



更新:如果我将Subscription.projects设置为一个列表而不是一个映射,并将JoinColumn添加到project.Subscription中,则会正常工作。但是,如果我将Subscription.projects更改为映射,则会开始获取org.hibernate.MappingException:再次重复列。显然,我确实希望使用映射,以便继续挖掘。

我认为您需要一个映射n
@AttributeOverride
要覆盖默认的联接列名:

@EmbeddedId
@AttributeOverride(name="subscriptionId", column=@Column(name="subscriptionId"))
private ProjectId id;

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

@JoinColumn(name = "subscriptionId", referencedColumnName = "id")

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

谢谢你的建议

以下是最终代码:

@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<>();
@可嵌入
公共类ProjectId实现了可序列化{
私有长订阅ID;
私有字符串名称;
@实体
@表(schema=“t”)
公共类项目{
@嵌入ID
私有投影id;
@许多酮
@MapsId(“订阅ID”)
@JoinColumn(name=“subscriptionId”,referencedColumnName=“id”,insertable=false,updateable=false)
私人认购;
@实体
@表(schema=“t”)
公开课订阅{
@OneToMany(mappedBy=“subscription”,cascade=CascadeType.ALL)
@映射键(name=“id”)
私有映射项目=新HashMap();

您使用
@MapsId
的目的是什么?您想实现什么?我有一个一对多关系,其中多个实体有一个包含一个实体id的复合键。我还在project的id字段和ProjectId中使用了AttributeOverride和AttributeOverride。这两种方法都不能解决问题。感谢您的建议,但是我试过了,但没有成功。请看上面。我想它可以与
@AttributeOverride(name=“subscription\u id”,column=@column(name=“subscriptionId”))一起工作
因为Hibernate在找到
@MapsId
时默认会生成
订阅id
名称。但是我还是希望使用
@JoinColumn
而不是依赖Hibernate的默认名称生成实现。谢谢,但是我尝试了这一点,但它不起作用,因为我出现了以下错误:“org.hibernate.MappingException:Repeated column”,如我在原始帖子中所述。最终解决方案请参见我的答案。您有两个问题,而列名问题是因为您需要联接列。第二个问题应该在单独的问题中,因为它与mapsId或所使用的列名无关。
@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<>();