org.hibernate.MappingException: Repeated column in mapping for collection: com.abc.entities.Packages.protectedItems column: account_id?

I am facing below error when doing ManyToMany mapping with Composite Keys -

Caused by: javax.persistence.PersistenceException: [PersistenceUnit:
default] Unable to build Hibernate SessionFactory; nested exception is
org.hibernate.MappingException: Repeated column in mapping for
collection:
com.abc.reports.entities.Packages.protectedItems column:
account_id

I have gone through other sof post with similar error but nothing much help full for my case I could find there. This error has become a blocker for my release and so any help will be greatly appreciated.

Basically I have compound primary key in both the tables and have a join table to map the ManyToMany relationship.

My Entity classes and Embeddable classes are as below -

Compound Keys

@Embeddable
@Getter
@Setter
@ToString
public class PackageId implements Serializable {

    private String accountId;

    private Long packageId;

}

@Embeddable
@Getter
@Setter
@ToString
public class ProtectedItemsId implements Serializable {

    private String accountId;

    private Long protectedItemId;

}

Entity Classes.
Packages.class.

@Entity
@Getter
@Setter
@ToString
public class Packages {

	@EmbeddedId
	private PackageId packageId;

	private String packageName;

	@ManyToMany(mappedBy = "packageItemsList")
	@JsonIgnore
	private List<ProtectedItems> protectedItems;
	
}

ProtectedItems.class

@Entity
@Getter
@Setter
public class ProtectedItems implements Serializable {

    @EmbeddedId
    private ProtectedItemsId protectedItemId;

    private String protectedItemName;

    @ManyToMany
    @JoinTable(
            name="jt_packages_protected_items",
            joinColumns = {@JoinColumn(name="accountId", insertable=false, updatable=false), @JoinColumn(name="protectedItemId", insertable=false, updatable=false)},
            inverseJoinColumns = {@JoinColumn(name="accountId", insertable=false, updatable=false), @JoinColumn(name="packageId", insertable=false, updatable=false)} )
    private List<Packages> packageItemsList;

    @ManyToMany(mappedBy = "protectedItemsList")
    @JsonIgnore
    private List<StreamMappings> streamMappings;

    @Override
    public String toString() {
        return "ProtectedItems{" +
                "protectedItemId=" + protectedItemId +
                ", protectedItemName='" + protectedItemName +
                ", packageItemsList=" + packageItemsList.hashCode() +
                ", streamMappings=" + streamMappings +
                '}';
    }
}

The hibernate error message is little helpful in identifying the problem even after looking at the above classes.
I can add the DB schema if that helps, but think it’s not necessary. Like said any help will be greatly appreciated as it will let me proceed with my release schedule.

the problem is that @JoinColumns and @InverseJoinColumns have a both a column with the same name accountId.
I would suggest you to change the @JoinColumns from accountId to protectedAccountId.

are you sure. It looks like the problem is w.r.t join table.
Join Table of Package and ProtectedItems has 3 columns → ( account_id, package_id and protected_item_id).
Hibernate seems to be expecting 4 columns. So I changed it to → ( p_account_id, package_id and pi_account_id, protected_item_id) and changed the mappings accordingly and it worked.
But i would prefer to keep 3 columns only as it was initially and make Hibernate accept this table design as it would fit my business case and not allow any data issues latter. Basically the account_id in all three tables refer to the same entity. Any suggestions will be greatly helpful on how to keep 3 columns and still make hibernate happy about it.

some one please do suggest how i can use just one account_id column in the join table. Duplicating the same seems to be inviting data errors.

I don’t think Hibernate can do this right now. You can create a JIRA issue for this improvement though. You can split up the ManyToMany association into two OneToMany associations to model this if you really want this.

public class ProtectedItems implements Serializable {

    @OneToMany(mappedBy = "protectedItem")
    private List<PackagesProtectedItem> packageItemsList;
...
}

public class Packages implements Serializable {

    @OneToMany(mappedBy = "package")
    private List<PackagesProtectedItem> protectedItems;
...
}

@Entity
@Table(name="jt_packages_protected_items")
public class PackagesProtectedItem implements Serializable {

    @Column(name = "accountId")
    private String accountId;
    @Column(name = "protectedItemId")
    private Long protectedItemId;
    @Column(name = "packageId")
    private Long packageId;

    @ManyToOne(fetch = LAZY)
    @JoinColumns({@JoinColumn(name="accountId", insertable=false, updatable=false), @JoinColumn(name="protectedItemId", insertable=false, updatable=false)}
    private ProtectedItems protectedItem;
    @JoinColumns( {@JoinColumn(name="accountId", insertable=false, updatable=false), @JoinColumn(name="packageId", insertable=false, updatable=false)} )
    private Packages package;
}

@beikov - thanks for the suggestion and informing about the limitation. I am ok with 4 columns in jt for now.