Ebean - Composite primary key which contains foreign keys
Asked Answered
M

1

8

I'm working with the last release of playframework (2.0.4) and the Ebean ORM. Here is my simplified db schema

TABLENAME (FIELD_NAME (, ...) )
User (id)
Group (id)
UserGroup (user_id, group_id, is_active)

I would like to create my entity models, like this :

@Entity
public class UserGroup extends Model {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    public UserGroupPK pk;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", insertable = false, updatable = false)
    public User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "group_id", insertable = false, updatable = false)
    public Group group;
}

@Embeddable
public class UserGroupPK implements Serializable{
    private static final long serialVersionUID = 1L;

    public Long userId;
    public Long groupId;

    public UserGroupPK(Long userId, Long groupId) {
        this.userId = userId;
        this.groupId = groupId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final UserGroupPK other = (UserGroupPK) obj;
        if ((this.userId == null) ? (other.userId != null) : !this.userId.equals(other.userId)) {
                return false;
            }
        if ((this.groupId == null) ? (other.groupId != null) : !this.groupId.equals(other.groupId)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 89 * hash + (this.userId != null ? this.userId.hashCode() : 0);
        hash = 89 * hash + (this.groupId != null ? this.groupId.hashCode() : 0);
        return hash;
    }
}

Is it right for you. And if it's ok for this intermediate table, what about the User and Group entity ? Thanks in advance.

Mylor answered 16/11, 2012 at 15:57 Comment(1)
Mapping wise, this is just fine. But good luck with making a finder for this class. I never managed to make Ebeans work normally with composite keys.Gettogether
S
4

Some annotations does not seem right but could work anyway.

If I were you I would do:

@Embeddable
public class UserGroupPK implements Serializable{
    private static final long serialVersionUID = 1L;

    @Column(name = "user_id")
    public Long userId;
    @Column(name = "group_id")
    public Long groupId;

For the ManyToOne column:

@ManyToOne
@JoinColumn(name = "user_id", referenceColumnName = "id", nullable = false) // insertable and updatable by default are true, which I think are correct here
public User user;

// same for group

In your User entity you need something like:

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
public Set<UserGroup> groups

When you do find, it's like

// find all users within a certain group
Ebean.find(User.class)
     .fetch("groups")
     .where().eq("groups.groupId", "...").findList();
Swore answered 6/4, 2014 at 21:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.