本帖最后由 bee_fc 于 2012-02-10 15:20:58 编辑

解决方案 »

  1.   

    你可以看看文档,
    2.2.6. 映射复合主键与外键
    组合主键使用一个可嵌入的类作为主键表示,因此你需要使用@Id 和@Embeddable两个注解. 还有一种方式是使用@EmbeddedId注解.注意所依赖的类必须实现 serializable以及实现equals()/hashCode()方法. 你也可以如Mapping identifier properties一章中描述的办法使用@IdClass注解.@Entity
    public class RegionalArticle implements Serializable {    @Id
        public RegionalArticlePk getPk() { ... }
    }@Embeddable
    public class RegionalArticlePk implements Serializable { ... }
             
    或者@Entity
    public class RegionalArticle implements Serializable {    @EmbeddedId
        public RegionalArticlePk getPk() { ... }
    }public class RegionalArticlePk implements Serializable { ... }
             
    @Embeddable 注解默认继承了其所属实体的访问类型, 除非显式使用了Hibernate的@AccessType注解(这个注解不是EJB3标准的一部分). 而@JoinColumns,即@JoinColumn数组, 定义了关联的组合外键(如果不使用缺省值的话). 显式指明referencedColumnNames是一个好的实践方式, 否则,Hibernate认为你使用的列顺序和主键声明的顺序一致.@Entity
    public class Parent implements Serializable {
        @Id
        public ParentPk id;
        public int age;    @OneToMany(cascade=CascadeType.ALL)
        @JoinColumns ({
            @JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
            @JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
            @JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
        })
        public Set<Child> children; //unidirectional
        ...
    }
             
    @Entity
    public class Child implements Serializable {
        @Id @GeneratedValue
        public Integer id;    @ManyToOne
        @JoinColumns ({
            @JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
            @JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
            @JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
        })
        public Parent parent; //unidirectional
    }
             
    @Embeddable
    public class ParentPk implements Serializable {
        String firstName;
        String lastName;
        ...
    }
             
    注意上面的 referencedColumnName显式使用方式.以上是文档上的。
      

  2.   

    public class GirlPK implements Serializable {
       
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(unique=true, nullable=false)
        private int id;
        private String name;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public boolean equal(Object obj){
            if(this == obj){
                return true;
            }
            if(obj != null && obj.getClass() == GirlPK.class){
                GirlPK target = (GirlPK)obj;
                if(target.getId() == getId() && target.getName().equals(getName())){
                    return true;
                }
            }
            return false;
        }
        public int hashCode(){
            return getId()*7+getName().hashCode();
        }
        
        
    }public class Girl {
        
        @EmbeddedId
        private GirlPK girlPK;
        private int age;
        public GirlPK getPeople() {
            return girlPK;
        }
        public void setPeople(GirlPK people) {
            this.girlPK = people;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        
    }
      

  3.   

    嗯,这些能看明白
    但是还有个问题是
    这个时候GirlPK的id怎么才能自增呢
    现在就算有@GeneratedValue(strategy=GenerationType.IDENTITY)
    它也不自增呀
      

  4.   

    现在加annotation那步已经过去了
    现在就是每次用hibernate自动建表的时候id字段上有identity,都没啥问题
    但是一插入新数据的时候就报错Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred while calling setter of test.GirlPK.id
    但是GirlPK里id也是int啊,肯定不存setter类型不匹配的情况