[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1338?page=c...
]
Airbus Deutschland commented on HHH-1338:
-----------------------------------------
The same problem occurs with xml definition-files.
Many to many fails when using mapped column with same name than other
column (from other side - entity).
--------------------------------------------------------------------------------------------------------
Key: HHH-1338
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1338
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.1
Environment: Hibernate 3.1
Dialect: Oracle
Hibernate Annottations: 3.1 b7
Reporter: Marcio Wesley Borges
Attachments: Hibernate.tar.gz
The bug that I will be describing occurs when using many-to-many mapping with entities
that have at least one column with same name.
Consider the following tables:
create table table_A (
col1 char(10) not null,
col2 char(10) not null,
something varchar(30) not null,
constraint pkA primary key (col1, col2)
);
create table table_B (
column1 char(10) not null,
col2 char(10) not null,
column3 char(10) not null,
something varchar(30) not null,
constraint pkB primary key (column1, col2, column3)
);
create table rel_AB (
col1 char(10) not null,
col2 char(10) not null,
column1 char(10) not null,
column3 char(10) not null,
constraint pkRelAB primary key (col1, col2, column1, column3),
constraint fkRelAB_A foreign key (col1, col2) references table_A(col1, col2),
constraint fkRelAB_B foreign key (column1, col2, column3) references table_B(column1,
col2, column3)
);
Also consider the following two java classes EntA and EntB:
/*
* EntA.java
*/
package org.hibernate.bugs.manytomany.b1;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Set;
@Entity(access=AccessType.PROPERTY)
@Table(name="table_A")
@IdClass(EntA.IdA.class)
public class EntA implements Serializable {
private String col1;
private String col2;
private String something;
private Set<EntB> bs;
public EntA() {
}
public EntA(String col1, String col2, String something) {
this.col1 = col1;
this.col2 = col2;
this.something = something;
}
//Start duplication of: EntA.IdA
@Column(name="col1", nullable=false)
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
@Column(name="col2", nullable=false)
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
public boolean equals(Object o) {
if (this==o)
return true;
if (! (o instanceof IdA) )
return false;
final IdA id = (IdA)o;
boolean equals;
equals = (getCol1()!=null) && (getCol1().equals(id.getCol1()))
&&
(getCol2()!=null) && (getCol2().equals(id.getCol2()));
return equals;
}
public int hashCode() {
int h1 = getCol1()==null ? 0 : getCol1().hashCode();
int h2 = getCol2()==null ? 0 : getCol2().hashCode();
int h = h1 + h2 * 29;
return h;
}
public String toString() {
return getCol1() + ':' + getCol2();
}
//End duplication of: EntA.IdA
@Column(name="something", nullable=false)
public String getSomething() {
return something;
}
public void setSomething(String something) {
this.something = something;
}
@ManyToMany(
targetEntity=EntB.class,
cascade=CascadeType.ALL
)
@JoinTable(
table=@Table(name="rel_AB"),
joinColumns={
@JoinColumn(name="col1", referencedColumnName="col1"),
@JoinColumn(name="col2", referencedColumnName="col2")
//<-- see here this column
},
inverseJoinColumns={
@JoinColumn(name="column1",
referencedColumnName="column1"),
@JoinColumn(name="col2", referencedColumnName="col2"),
//<-- now the same column here, but to link the other side
@JoinColumn(name="column3",
referencedColumnName="column3")
}
)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN } )
public Set<EntB> getBs() {
return bs;
}
public void setBs(Set<EntB> bs) {
this.bs = bs;
}
@Embeddable(access = AccessType.PROPERTY)
public static class IdA implements Serializable {
private String col1;
private String col2;
public IdA() {}
public IdA(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
@Column(name="col1", nullable=false)
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
@Column(name="col2", nullable=false)
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
public boolean equals(Object o) {
if (this==o)
return true;
if (! (o instanceof IdA) )
return false;
final IdA id = (IdA)o;
boolean equals;
equals = (getCol1()!=null) && (getCol1().equals(id.getCol1()))
&&
(getCol2()!=null) && (getCol2().equals(id.getCol2()));
return equals;
}
public int hashCode() {
int h1 = getCol1()==null ? 0 : getCol1().hashCode();
int h2 = getCol2()==null ? 0 : getCol2().hashCode();
int h = h1 + h2 * 29;
return h;
}
public String toString() {
return getCol1() + ':' + getCol2();
}
}
}
/*
* EntB.java
*/
package org.hibernate.bugs.manytomany.b1;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Set;
@Entity(access=AccessType.PROPERTY)
@Table(name="table_B")
@IdClass(EntB.IdB.class)
public class EntB implements Serializable {
private String column1;
private String col2;
private String column3;
private String something;
private Set<EntA> as;
/**
* Creates a new instance of EntB
*/
public EntB() {
}
public EntB(String column1, String col2, String column3, String something) {
this.column1 = column1;
this.col2 = col2;
this.column3 = column3;
this.something = something;
}
//Start duplication of: EntB.IdB
@Column(name="column1", nullable=false)
public String getColumn1() {
return column1;
}
public void setColumn1(String column1) {
this.column1 = column1;
}
@Column(name="col2", nullable=false)
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
@Column(name="column3", nullable=false)
public String getColumn3() {
return column3;
}
public void setColumn3(String column3) {
this.column3 = column3;
}
public boolean equals(Object o) {
if (this==o)
return true;
if (! (o instanceof IdB) )
return false;
final IdB id = (IdB)o;
boolean equals;
equals = (getColumn1()!=null) &&
(getColumn1().equals(id.getColumn1())) &&
(getCol2()!=null) && (getCol2().equals(id.getCol2()))
&&
(getColumn3()!=null) &&
(getColumn3().equals(id.getColumn3()));
return equals;
}
public int hashCode() {
int h1 = getColumn1()==null ? 0 : getColumn1().hashCode();
int h2 = getCol2()==null ? 0 : getCol2().hashCode();
int h3 = getColumn3()==null ? 0 : getColumn3().hashCode();
int h = h1 + h2 * 29 + h3 * 43;
return h;
}
public String toString() {
return getColumn1() + ':' + getCol2() + ':' + getColumn3();
}
//End duplication of: EntB.IdB
@Column(name="something", nullable=false)
public String getSomething() {
return something;
}
public void setSomething(String something) {
this.something = something;
}
@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},
mappedBy="bs",
targetEntity=EntA.class,
fetch=FetchType.LAZY)
@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.ALL } )
public Set<EntA> getAs() {
return as;
}
public void setAs(Set<EntA> as) {
this.as = as;
}
@Embeddable(access = AccessType.PROPERTY)
public static class IdB implements Serializable {
private String column1;
private String col2;
private String column3;
public IdB() {}
public IdB(String column1, String col2, String column3) {
this.column1 = column1;
this.col2 = col2;
this.column3 = column3;
}
@Column(name="column1", nullable=false)
public String getColumn1() {
return column1;
}
public void setColumn1(String column1) {
this.column1 = column1;
}
@Column(name="col2", nullable=false)
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
@Column(name="column3", nullable=false)
public String getColumn3() {
return column3;
}
public void setColumn3(String column3) {
this.column3 = column3;
}
public boolean equals(Object o) {
if (this==o)
return true;
if (! (o instanceof IdB) )
return false;
final IdB id = (IdB)o;
boolean equals;
equals = (getColumn1()!=null) &&
(getColumn1().equals(id.getColumn1())) &&
(getCol2()!=null) && (getCol2().equals(id.getCol2()))
&&
(getColumn3()!=null) &&
(getColumn3().equals(id.getColumn3()));
return equals;
}
public int hashCode() {
int h1 = getColumn1()==null ? 0 : getColumn1().hashCode();
int h2 = getCol2()==null ? 0 : getCol2().hashCode();
int h3 = getColumn3()==null ? 0 : getColumn3().hashCode();
int h = h1 + h2 * 29 + h3 * 43;
return h;
}
public String toString() {
return getColumn1() + ':' + getCol2() + ':' + getColumn3();
}
}
}
The error occurs while the Hibernate is mapping and it raises:
Exception in thread "main" org.hibernate.MappingException: Repeated column in
mapping for collection: org.hibernate.bugs.manytomany.b1.EntB.as column: col2
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:290)
at org.hibernate.mapping.Collection.checkColumnDuplication(Collection.java:313)
at org.hibernate.mapping.Collection.validate(Collection.java:270)
at org.hibernate.mapping.Set.validate(Set.java:19)
at org.hibernate.cfg.Configuration.validate(Configuration.java:987)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1147)
at ...
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira