2014-07-21 85 views
2

儘管在網絡上顯示了所有示例,但我仍無法使@MapsId正常工作。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> 

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); 

ProjectId.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<>(); 

當我做一個插入,以下錯誤發生:

Hibernate: insert into t.Project (name, subscription_id) values (?, ?) 2014-07-20 11:06:59,193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1054, SQLState: 42S22 2014-07-20 11:06:59,193 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Unknown column 'subscription_id' in 'field list'

...

... 94 more Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'subscription_id' in 'field list' at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at com.mysql.jdbc.Util.handleNewInstance(Util.java:408) at 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) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2334) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2262) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2246) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187) ... 114 more

如果我取消了@JoinColumnProject.subscription和重新部署我得到此錯誤:

... 21 more Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: t.Subscription.projects column: subscriptionId

我也嘗試刪除@MapsId,我仍然得到重複的列錯誤。

我很難過如何解決這個問題。任何建議,將不勝感激。

感謝


更新:如果我做一個Subscription.projects列表,而不是一個地圖,我添加了JoinColumn到project.subscription它的工作原理。但是,如果我將subscription.projects更改回地圖,則會重新獲取org.hibernate.MappingException:重複列。很明顯,我真的很想使用地圖,所以我會繼續挖掘。

+0

瓦at是你使用'@ MapsId'的關鍵所在?你想實現什麼? –

+0

我有一對多關係,其中許多實體具有包含一個實體ID的組合鍵。 – Rian

+0

我也在項目的id字段和ProjectId中使用了AttributeOverride和AttributeOverride。既不解決問題。 – Rian

回答

1

好了,問題是,我需要添加@MapKey否則subscription.projects它將與抱怨「 org.hibernate.MappingException:重複列」當我添加了@JoinColumn

感謝您的建議

下面是最終代碼:

@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<>(); 
1

我想你需要一個@AttributeOverride覆蓋默認連接列名稱:

@EmbeddedId 
@AttributeOverride(name="subscriptionId", [email protected](name="subscriptionId")) 
private ProjectId id; 
+0

感謝您的建議,但是我已經嘗試過了,但沒有奏效。請參閱上文。 – Rian

0

當使用mapsId註釋您指定的關係,股票和控制由ID映射映射的領域,所以在現場關係映射將覆蓋Id映射中的字段。這意味着,JPA將使用默認subscription_id除非你指定連接你註釋掉柱:

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

謝謝,但我試過,它不工作,因爲我然後得到以下錯誤:「org.hibernate.MappingException:重複列」,如我原來的帖子中所述。查看我的答案以獲得最終解 – Rian

+0

您有兩個問題,列名問題是因爲您需要連接列。你的第二個問題應該在一個單獨的問題中,因爲它與mapsId或使用的列名無關。 – Chris