Ali
Ali

Reputation: 267287

Mapping a one to many relationship in Hibernate?

I have two tables, a user table and a user_avatar table. For each user, there are 3 records in the user_avatar table, for 3 sizes of avatars (large, medium, small).

The user_avatar table has a userId column which refers to the User.id field to specify to which user an avatar belongs to.

Here's my UserAvatar class:

@Entity @Table(name = "user_avatar")

public class UserAvatar
{
    @Id @GeneratedValue
    private long id;

    @ManyToOne
    @JoinColumn(name = "userId")
    private User user;

    @Enumerated(EnumType.STRING)
    private AvatarSize size;

    private String file;
    private String s3Key;

    @Override
    public String toString()
    {
        return size + " " + file;
    }
}

And here's how I'm referring to it in the `user

@Entity
public class User
{
    @Id @GeneratedValue
    public Long id;

    @OneToMany
    @JoinColumn(name = "id")
    @OrderColumn(name = "id")
    public UserAvatar[] avatar; //declared array as there'd be at least 3 records
}

When I run this code, I get the error:

Repeated column in mapping for collection: com.xxx.User.avatar column: id

What am I doing wrong?

Upvotes: 4

Views: 1877

Answers (2)

theblang
theblang

Reputation: 10425

What you are doing here is a bidrectional many-to-one, where you want to populate objects on both sides of the relationship.

Hibernate will complain if you have a JoinColumn on both sides, so just put it on the "owning" side and add mappedBy to the other side.

See this example:

public class UserAvatar {
    ...

    @ManyToOne
    @JoinColumn(name="userId") // userId is the name of your database FK column
    private User user;

    ...
}

public class User {
    ...

    @OneToMany(mappedBy="user")
    public List<UserAvatar> avatars;

    ...
}

As for the particular error you were getting, I believe that was caused by JoinColumn("id") in User conflicting with the primary key column id.

Also see this SO answer.

Upvotes: 4

Peter Bratton
Peter Bratton

Reputation: 6408

Hibernate will maintain an association's order when you use a List or an array. To do that, it needs an integer column in the many-side table to store the record's position in the List/array. You can either:

  1. Change your field to use a Set, for which Hibernate will not attempt to maintain ordering.
  2. Add an integer type column to your database to store the record order, and name that in the @OrderColumn annotation.

Upvotes: 1

Related Questions