问题
This is a strange scenario born of the fact that I am working with a legacy system who's structure I cannot change.
The scenario is that I have a Element table that contains various data about an element with to important fields "type" and a "value".
Various combinations of type and value are categorised. For instance, all Elements of type 2 and value "green" belong to category 1.
I'm building a user interface in to the legacy system that lets users define these categories given a type and and a value (obviously). What I want is for the legacy system to include a set of Categories in it's hibernate Entity. a Category is actually an Enum of type ElementCategory, one of my remits is that the legacy app has to be the one to define my schema so it needs to build up my tables when I fire it up. and then I use that database when I create my new front end. Here's how I've annotated my new collection within my Element Entity:
@CollectionOfElements(fetch=FetchType.EAGER,targetElement = ElementCategory.class)
@JoinTable(name = "Element_Category",joinColumns =
{@JoinColumn(name = "type", referencedColumnName="type"
@JoinColumn(name = "value", referencedColumnName="value")
})
@Column(name="category")
@Enumerated(EnumType.STRING)
public List<ElementCategory> getCategories() {
return categories;
}
The problem is that when I fire up the server the Element table that's created has a unique constraint on (type, value), which is incorrect, there can be multiple Elements with the same type and value fields, they just belong to the same category OR categories, depending on how the element_category table looks.
I know that what I have is a many to many set up, but I can;t use many to many unless my Elements category field contains a collection of Category Entities, but it doesn't it's just a set of enums.
Can this be achieved with hibernate at all?
Following on from this issues I tried another approach and created the ElementCategory Entity:
@Entity
@Table(name="ElementCategory")
public class ElementCategory implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private int id;
private String description;
public int getId() {
return id;
}
public void setId(int id) {
this.id =id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int hash = 1;
hash = hash * (17 + id);
hash = hash * 31 + description.hashCode();
return hash;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(!super.equals(obj)) {
return false;
}
if(getClass() != obj.getClass()) {
return false;
}
ElementCategory other = (ElementCategory)obj;
return ((other.id == id) && (this.description.equals(other.description)));
}
}
mapping this in my Element Entity class like this:
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "ELEMENT_ELEMENTCATOGORY", joinColumns = {
@JoinColumn(name = "type", referencedColumnName = "type"),
@JoinColumn(name = "value", referencedColumnName = "value") })
@Column(name = "category")
public List<ElementCategory> getCategories() {
return categories;
}
I have tried putting $unique=false$ all over the shop but the generated tables still end up with this in my Element table:
CONSTRAINT element_type_value_key UNIQUE (type , value )
I don't want it to be unique, multiple element can have that configuration.
回答1:
you could try something like this:
@JoinTable(name = "Element_Category",
joinColumns = {@JoinColumn(name = "type_id") },
inverseJoinColumns = { @JoinColumn(name = "elementcategory_id") }
)
public List<ElementCategory> getCategories() {
return categories;
}
来源:https://stackoverflow.com/questions/9213122/hibernate-jpa-collection-of-elements-with-many-to-many-relationship