0

I have two entity classes Activity and User. The relationships between them are:

  • One Activity can have one or many User
  • One User can belongs to one or many Activity

So to achieve this I have defined @ManyToMany mapping between them. Below is my classes:

Activity:

@javax.persistence.Entity
@Table(name = "ACTIVITY")
public class Activity extends Entity {

    @Transient
    private static final long serialVersionUID = 4741665931936809028L;

    private Set<User> users;

    public Activity() {
        super();
    }

    @ManyToMany(targetEntity = User.class, cascade = { CascadeType.ALL })
    @JoinTable(name = "ACTIVITY_USER", joinColumns = @JoinColumn(name = "ID"), inverseJoinColumns = @JoinColumn(name = "ID"))
    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }
}

User:

@javax.persistence.Entity
@Table(name = "USER")
public class User extends Entity {

    @Transient
    private static final long serialVersionUID = -112950002831333869L;

    private Set<Activity> activities;

    public User() {
        super();
    }

    @ManyToMany(cascade = { CascadeType.ALL }, mappedBy = "users", targetEntity = Activity.class)
    public Set<Activity> getActivities() {
        return activities;
    }

    public void setActivities(Set<Activity> activities) {
        this.activities = activities;
    }
}

Both of the above classes extends Entity:

@MappedSuperclass
public class Entity implements Serializable {

    @Transient
    private static final long serialVersionUID = 7470288121057059283L;

    private Long id;

    public Entity() {
        super();
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", updatable = false, nullable = false, unique = true)
    public Long getId() {
        return id;
    }

    @SuppressWarnings("unused")
    private void setId(Long id) {
        this.id = id;
    }

    public void setLastUpdateTimestamp(Date lastUpdateTimestamp) {
        this.lastUpdateTimestamp = lastUpdateTimestamp;
    }


    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        return prime * result + ((getId() == null) ? super.hashCode() : getId().hashCode());
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj == null) {
            return false;
        }

        if (!getClass().equals(HibernateProxyHelper.getClassWithoutInitializingProxy(obj))) {
            return false;
        }

        final Entity other = (Entity) obj;

        if (getId() != other.getId()) {
            if (getId() == null) {
                return false;
            }
            if (!getId().equals(other.getId())) {
                return false;
            }
        }

        return true;
    }
}

Now from:

@JoinTable(name = "ACTIVITY_USER", joinColumns = @JoinColumn(name = "ID"), inverseJoinColumns = @JoinColumn(name = "ID"))

what I understand that the name of the @JoinColumn of joinColumns takes the column name of the PK of one entity and the name of the @JoinColumn of inverseJoinColumns takes the column name of the PK of another entity. But in my case both of the column names are same, i.e., ID from the Entity class.

My question is how can I avoid this confliction of the column names? Any suggestion would be very helpful to me.

Tapas Bose
  • 28,796
  • 74
  • 215
  • 331

1 Answers1

5

It makes no sense to have two columns wit the same name in the same table. So just choose a different name for the columns.

Change

@JoinTable(name = "ACTIVITY_USER", 
           joinColumns = @JoinColumn(name = "ID"), 
           inverseJoinColumns = @JoinColumn(name = "ID"))

to

@JoinTable(name = "ACTIVITY_USER", 
           joinColumns = @JoinColumn(name = "ACTIVITY_ID"), 
           inverseJoinColumns = @JoinColumn(name = "USER_ID"))

As the name of the attribute indicates, the name you give there is the name of the join column, part of the join table, i.e. the name of the column holding the foreign key to the activity or user table, in the join table ACTIVITY_USER. Hibernate already know the name of the PK of User and Activity: you told it in their respective @Id annotation.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255