复杂的多对一双向关系求解(多端联合主键,其中一个键为一端的主键)

经网上查阅资料仍没有找到解决方法

不知该如何写两个pojo的配置文件

向各位达人请教



一端——Product

public class Product {
private Long productId; //id
private String productName; //名称
private Set featureSet; //特性集合
.....
}




多端——Feature

public class Feature implements Serializable {
private Integer featureId;
private String featureName;
private Product product;
....
}




数据库中Feature表的主键为productId和featureId组成的联合主键,并且featureId由我们自己set值(并非sequence)



请教各位达人

万分感谢

[code="sql"]
create table product (
product_id bigint primary key,
product_name varchar(255)
);

create table feature (
feature_id bigint,
feature_name varchar(255),
product_id bigint,
primary key(feature_id, product_id),
foreign key (product_id) reference product(product_id)
);
[/code]

[code="xml"]
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

package="domain">

<class
    name="Product"
    table="product"
    dynamic-insert="true"
    >

    <id
        name="productId"
        column="product_id">
        <generator class="sequence" >
            <param name="sequence">seq</param>
        </generator>
    </id>

    <property name="productName" column="product_name" />

    <set name="featureSet" inverse="true" cascade="all">
        <key column="product_id" not-null="true" />
        <one-to-many class="Feature" />
    </set>

</class>

[/code]

[code="xml"]
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

package="domain">

<class
    name="Feature"
    table="feature"
    dynamic-insert="true"
    >

    <composite-id>
        <key-property name="featureId" column="feature_id" />
        <key-many-to-one name="product" column="product_id" class="Product" />
    </composite-id>

    <property name="featureName" column="feature_name" />

</class>

[/code]

[code="java"]
package domain;

import java.io.Serializable;

public class Feature implements Serializable {

private Long featureId;
private String featureName;
private Product product;

public Feature() {
    super();
}

public Long getFeatureId() {
    return featureId;
}
public void setFeatureId(Long featureId) {
    this.featureId = featureId;
}
public String getFeatureName() {
    return featureName;
}
public void setFeatureName(String featureName) {
    this.featureName = featureName;
}
public Product getProduct() {
    return product;
}
public void setProduct(Product product) {
    this.product = product;
}

@Override
public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + ((featureName == null) ? 0 : featureName.hashCode());
    result = PRIME * result + ((product == null) ? 0 : product.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    final Feature other = (Feature) obj;
    if (featureName == null) {
        if (other.featureName != null)
            return false;
    } else if (!featureName.equals(other.featureName))
        return false;
    if (product == null) {
        if (other.product != null)
            return false;
    } else if (!product.equals(other.product))
        return false;
    return true;
}

}

[/code]

[code="java"]
package domain;

import java.io.Serializable;
import java.util.Set;
import java.util.HashSet;

public class Product implements Serializable {

private Long productId;
private String productName;
private Set featureSet = new HashSet<Feature>();

public Product() {
    super();
}

public Set getFeatureSet() {
    return featureSet;
}
public void setFeatureSet(Set featureSet) {
    this.featureSet = featureSet;
}
public Long getProductId() {
    return productId;
}
public void setProductId(Long productId) {
    this.productId = productId;
}
public String getProductName() {
    return productName;
}
public void setProductName(String productName) {
    this.productName = productName;
}
public void addFeature(Feature f) {
    removeFeature(f);
    getFeatureSet().add(f);
    f.setProduct(this);
}
public void removeFeature(Feature f) {
    if(f == null) {
        throw new IllegalArgumentException("feature is null");
    }

    if(f.getProduct() != null && f.getProduct().getFeatureSet() != null) {
        f.getProduct().getFeatureSet().remove(f);
    }

    f.setProduct(null);
}

@Override
public int hashCode() {
    final int PRIME = 31;
    int result = 1;
    result = PRIME * result + ((productName == null) ? 0 : productName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    final Product other = (Product) obj;
    if (productName == null) {
        if (other.productName != null)
            return false;
    } else if (!productName.equals(other.productName))
        return false;
    return true;
}

}

[/code]

[code="java"]
package app;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import domain.*;

public class Test {

public static void main(String[] args) {
    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Feature f1 = new Feature();
    f1.setFeatureId(Long.valueOf(1));
    f1.setFeatureName("1");

    Feature f2 = new Feature();
    f2.setFeatureId(Long.valueOf(2));
    f2.setFeatureName("2");

    Feature f3 = new Feature();
    f3.setFeatureId(Long.valueOf(3));
    f3.setFeatureName("3");

    Product p = new Product();
    p.setProductName("a");
    p.addFeature(f1);
    p.addFeature(f2);
    p.addFeature(f3);

    session.save(p);

    tx.commit();
    session.close();
    sessionFactory.close();
}

}

[/code]