Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA @MapsId inserting incorrect column name

I am having trouble getting @MapsId to work, despite following all the examples on the net.

Here is my the setup:

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 scripts:

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

When I do an insert, the following error happens:

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

If I uncomment the @JoinColumn on Project.subscription and redeploy I get this error:

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

I've also tried removing the @MapsId, I still get the repeated column error.

I am stumped as to how to get around this. Any suggestions would be appreciated.

Thanks


Update: If I make Subscription.projects a list instead of a map and I add the JoinColumn to project.subscription it works. However if I change subscription.projects back to a map, I start getting the org.hibernate.MappingException: Repeated column again. Obviously I would really like to use the Map so I'll keep digging.

like image 800
Rian Avatar asked Jul 21 '14 18:07

Rian


2 Answers

Ok, so the problem was that I needed to add @MapKey to subscription.projects otherwise it will complain with "org.hibernate.MappingException: Repeated column" when I add the @JoinColumn

Thanks for the suggestions

Here is the final code:

@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<>();
like image 147
Rian Avatar answered Oct 21 '22 21:10

Rian


When using the mapsId annotation you specify that the relationship shares and controls the field mapped by the Id mapping, so the field in the relationship mapping overrides the field in the Id mapping. This means that JPA will use the subscription_id default unless you specify the join column that you commented out:

@JoinColumn(name = "subscriptionId", referencedColumnName = "id")
like image 10
Chris Avatar answered Oct 21 '22 19:10

Chris