Hibernate 4,无法使用复合主键持久化实体

Hibernate 4,无法使用复合主键持久化实体,hibernate,persistence,composite-primary-key,Hibernate,Persistence,Composite Primary Key,我想持久化包含复合主键的实体。 连接到数据库并创建表,但插入新行失败 Student.java: @Entity @Table(name = "student") public class Student extends BaseEntity implements Serializable{ /** * */ private static final long serialVersionUID = -6801103333234228955L; p

我想持久化包含复合主键的实体。 连接到数据库并创建表,但插入新行失败

Student.java:

@Entity
@Table(name = "student")
public class Student extends BaseEntity implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = -6801103333234228955L;

    private Integer studentId;
    private String cin;
    private String firstName;
    private String lastName;
    private Integer age;
    private String phone;
    private String mail;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "STUDENT_ID", nullable = false)
    public Integer getStudentId() {
        return studentId;
    }

    public void setStudentId(Integer studentId) {
        this.studentId = studentId;
    }

    @Id
    @Column(name = "CIN", unique= true, nullable = false, length = 8)
    public String getCin() {
        return cin;
    }

    public void setCin(String cin) {
        this.cin = cin;
    }

    @Column(name = "FIRST_NAME", nullable = false, length = 25)
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @Column(name = "LAST_NAME", nullable = false, length = 20)
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @Column(name = "AGE")
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Column(name = "PHONE", nullable = false, length = 20)
    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Column(name = "MAIL", length = 30)
    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

}
BaseEntity.java:

public abstract class BaseEntity {

    private String id = IdGenerator.createId();

    private Integer version = null;

    public String getId() {
        return this.id;
    }

    public void setId(String value) {
        this.id = value;
    }

    public Integer getVersion() {
        return this.version;
    }

    public void setVersion(Integer value) {
        this.version = value;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || !(o instanceof BaseEntity )) {
            return false;
        }

        BaseEntity other  = (BaseEntity ) o;

        // if the id is missing, return false
        if (id == null) return false;

        // equivalence by id
        return id.equals(other.getId());
    }

    public int hashCode() {
        if (id != null) {
            return id.hashCode();
        } else {
            return super.hashCode();
        }
    }

    public String toString() {
        return this.getClass().getName()
            + "[id=" + id + "]";
    }

    public boolean isCreation() {
        return version == null;
    }

    public void regenerateId() {
        id = IdGenerator.createId();
        version = null;
    }
}
IdGenerator.java:

public class IdGenerator {

    public static String createId() {
        UUID uuid = java.util.UUID.randomUUID();
        return uuid.toString();
    }

}
MainTest.java:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class MainTest{

    private static final  Logger logger = LoggerFactory.getLogger(MainTest.class);

    @Autowired
    StudentDao studentDao;

    @Test
    public void testStudent(){
        Student student = new Student();
        student.setCin("05454447");
        student.setFirstName("student1");
        student.setLastName("student1");
        student.setAge(27);
        student.setPhone("4578979");
        student.setMail("d@d.com");
        Integer id = studentDao.create(student);
        logger.info("student id : "+ id);
    }

}
日志:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/SSAIDI/.m2/repository/org/slf4j/slf4j-log4j12/1.7.7/slf4j-log4j12-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/SSAIDI/.m2/repository/ch/qos/logback/logback-classic/1.1.2/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
log4j:WARN No such property [minIndex] in org.apache.log4j.RollingFileAppender.
log4j:WARN No such property [maxIndex] in org.apache.log4j.RollingFileAppender.
12:01:14,187  INFO XmlBeanDefinitionReader:316 - Loading XML bean definitions from class path resource [applicationContext.xml]
12:01:14,423  INFO GenericApplicationContext:513 - Refreshing org.springframework.context.support.GenericApplicationContext@20a6a283: startup date [Fri Aug 15 12:01:14 GMT+01:00 2014]; root of context hierarchy
12:01:14,524  INFO PropertySourcesPlaceholderConfigurer:172 - Loading properties file from class path resource [persistence-mysql.properties]
12:01:14,755 DEBUG BasicTypeRegistry:146 - Adding type registration boolean -> org.hibernate.type.BooleanType@7d7d7924
12:01:14,756 DEBUG BasicTypeRegistry:146 - Adding type registration boolean -> org.hibernate.type.BooleanType@7d7d7924
12:01:14,756 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Boolean -> org.hibernate.type.BooleanType@7d7d7924
12:01:14,757 DEBUG BasicTypeRegistry:146 - Adding type registration numeric_boolean -> org.hibernate.type.NumericBooleanType@457def5b
12:01:14,758 DEBUG BasicTypeRegistry:146 - Adding type registration true_false -> org.hibernate.type.TrueFalseType@353ff34d
12:01:14,759 DEBUG BasicTypeRegistry:146 - Adding type registration yes_no -> org.hibernate.type.YesNoType@3a9c7d64
12:01:14,761 DEBUG BasicTypeRegistry:146 - Adding type registration byte -> org.hibernate.type.ByteType@969f4cd
12:01:14,761 DEBUG BasicTypeRegistry:146 - Adding type registration byte -> org.hibernate.type.ByteType@969f4cd
12:01:14,761 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Byte -> org.hibernate.type.ByteType@969f4cd
12:01:14,762 DEBUG BasicTypeRegistry:146 - Adding type registration character -> org.hibernate.type.CharacterType@530ee71b
12:01:14,763 DEBUG BasicTypeRegistry:146 - Adding type registration char -> org.hibernate.type.CharacterType@530ee71b
12:01:14,763 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Character -> org.hibernate.type.CharacterType@530ee71b
12:01:14,765 DEBUG BasicTypeRegistry:146 - Adding type registration short -> org.hibernate.type.ShortType@268aadef
12:01:14,766 DEBUG BasicTypeRegistry:146 - Adding type registration short -> org.hibernate.type.ShortType@268aadef
12:01:14,767 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Short -> org.hibernate.type.ShortType@268aadef
12:01:14,768 DEBUG BasicTypeRegistry:146 - Adding type registration integer -> org.hibernate.type.IntegerType@1f12853f
12:01:14,768 DEBUG BasicTypeRegistry:146 - Adding type registration int -> org.hibernate.type.IntegerType@1f12853f
12:01:14,768 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Integer -> org.hibernate.type.IntegerType@1f12853f
12:01:14,770 DEBUG BasicTypeRegistry:146 - Adding type registration long -> org.hibernate.type.LongType@191a248
12:01:14,770 DEBUG BasicTypeRegistry:146 - Adding type registration long -> org.hibernate.type.LongType@191a248
12:01:14,770 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Long -> org.hibernate.type.LongType@191a248
12:01:14,772 DEBUG BasicTypeRegistry:146 - Adding type registration float -> org.hibernate.type.FloatType@4443baa7
12:01:14,772 DEBUG BasicTypeRegistry:146 - Adding type registration float -> org.hibernate.type.FloatType@4443baa7
12:01:14,772 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Float -> org.hibernate.type.FloatType@4443baa7
12:01:14,773 DEBUG BasicTypeRegistry:146 - Adding type registration double -> org.hibernate.type.DoubleType@7909298b
12:01:14,774 DEBUG BasicTypeRegistry:146 - Adding type registration double -> org.hibernate.type.DoubleType@7909298b
12:01:14,774 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Double -> org.hibernate.type.DoubleType@7909298b
12:01:14,776 DEBUG BasicTypeRegistry:146 - Adding type registration big_decimal -> org.hibernate.type.BigDecimalType@4efdd8b
12:01:14,776 DEBUG BasicTypeRegistry:146 - Adding type registration java.math.BigDecimal -> org.hibernate.type.BigDecimalType@4efdd8b
12:01:14,778 DEBUG BasicTypeRegistry:146 - Adding type registration big_integer -> org.hibernate.type.BigIntegerType@513925a
12:01:14,778 DEBUG BasicTypeRegistry:146 - Adding type registration java.math.BigInteger -> org.hibernate.type.BigIntegerType@513925a
12:01:14,779 DEBUG BasicTypeRegistry:146 - Adding type registration string -> org.hibernate.type.StringType@79a70972
12:01:14,779 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.String -> org.hibernate.type.StringType@79a70972
12:01:14,780 DEBUG BasicTypeRegistry:146 - Adding type registration nstring -> org.hibernate.type.StringNVarcharType@4d83f728
12:01:14,781 DEBUG BasicTypeRegistry:146 - Adding type registration ncharacter -> org.hibernate.type.CharacterNCharType@16a1fa7f
12:01:14,782 DEBUG BasicTypeRegistry:146 - Adding type registration url -> org.hibernate.type.UrlType@368c7bd5
12:01:14,782 DEBUG BasicTypeRegistry:146 - Adding type registration java.net.URL -> org.hibernate.type.UrlType@368c7bd5
12:01:14,784 DEBUG BasicTypeRegistry:146 - Adding type registration date -> org.hibernate.type.DateType@55a71fa6
12:01:14,784 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.Date -> org.hibernate.type.DateType@55a71fa6
12:01:14,786 DEBUG BasicTypeRegistry:146 - Adding type registration time -> org.hibernate.type.TimeType@687f705e
12:01:14,786 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.Time -> org.hibernate.type.TimeType@687f705e
12:01:14,788 DEBUG BasicTypeRegistry:146 - Adding type registration timestamp -> org.hibernate.type.TimestampType@4caa1b37
12:01:14,788 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.Timestamp -> org.hibernate.type.TimestampType@4caa1b37
12:01:14,788 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.Date -> org.hibernate.type.TimestampType@4caa1b37
12:01:14,789 DEBUG BasicTypeRegistry:146 - Adding type registration dbtimestamp -> org.hibernate.type.DbTimestampType@7313c51
12:01:14,791 DEBUG BasicTypeRegistry:146 - Adding type registration calendar -> org.hibernate.type.CalendarType@65c98bf3
12:01:14,791 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.Calendar -> org.hibernate.type.CalendarType@65c98bf3
12:01:14,791 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.CalendarType@65c98bf3
12:01:14,792 DEBUG BasicTypeRegistry:146 - Adding type registration calendar_date -> org.hibernate.type.CalendarDateType@551ea5f4
12:01:14,793 DEBUG BasicTypeRegistry:146 - Adding type registration locale -> org.hibernate.type.LocaleType@64bb9a0a
12:01:14,793 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.Locale -> org.hibernate.type.LocaleType@64bb9a0a
12:01:14,794 DEBUG BasicTypeRegistry:146 - Adding type registration currency -> org.hibernate.type.CurrencyType@75304935
12:01:14,794 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.Currency -> org.hibernate.type.CurrencyType@75304935
12:01:14,795 DEBUG BasicTypeRegistry:146 - Adding type registration timezone -> org.hibernate.type.TimeZoneType@1004243a
12:01:14,796 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.TimeZone -> org.hibernate.type.TimeZoneType@1004243a
12:01:14,797 DEBUG BasicTypeRegistry:146 - Adding type registration class -> org.hibernate.type.ClassType@ddc5a99
12:01:14,797 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Class -> org.hibernate.type.ClassType@ddc5a99
12:01:14,798 DEBUG BasicTypeRegistry:146 - Adding type registration uuid-binary -> org.hibernate.type.UUIDBinaryType@67728a26
12:01:14,799 DEBUG BasicTypeRegistry:146 - Adding type registration java.util.UUID -> org.hibernate.type.UUIDBinaryType@67728a26
12:01:14,799 DEBUG BasicTypeRegistry:146 - Adding type registration uuid-char -> org.hibernate.type.UUIDCharType@6ce18074
12:01:14,800 DEBUG BasicTypeRegistry:146 - Adding type registration pg-uuid -> org.hibernate.type.PostgresUUIDType@72f8516e
12:01:14,801 DEBUG BasicTypeRegistry:146 - Adding type registration binary -> org.hibernate.type.BinaryType@4a8716d3
12:01:14,801 DEBUG BasicTypeRegistry:146 - Adding type registration byte[] -> org.hibernate.type.BinaryType@4a8716d3
12:01:14,802 DEBUG BasicTypeRegistry:146 - Adding type registration [B -> org.hibernate.type.BinaryType@4a8716d3
12:01:14,803 DEBUG BasicTypeRegistry:146 - Adding type registration wrapper-binary -> org.hibernate.type.WrapperBinaryType@309c3c24
12:01:14,803 DEBUG BasicTypeRegistry:146 - Adding type registration Byte[] -> org.hibernate.type.WrapperBinaryType@309c3c24
12:01:14,803 DEBUG BasicTypeRegistry:146 - Adding type registration [Ljava.lang.Byte; -> org.hibernate.type.WrapperBinaryType@309c3c24
12:01:14,804 DEBUG BasicTypeRegistry:146 - Adding type registration image -> org.hibernate.type.ImageType@42357933
12:01:14,805 DEBUG BasicTypeRegistry:146 - Adding type registration characters -> org.hibernate.type.CharArrayType@4c71df84
12:01:14,805 DEBUG BasicTypeRegistry:146 - Adding type registration char[] -> org.hibernate.type.CharArrayType@4c71df84
12:01:14,805 DEBUG BasicTypeRegistry:146 - Adding type registration [C -> org.hibernate.type.CharArrayType@4c71df84
12:01:14,806 DEBUG BasicTypeRegistry:146 - Adding type registration wrapper-characters -> org.hibernate.type.CharacterArrayType@45196f3b
12:01:14,807 DEBUG BasicTypeRegistry:146 - Adding type registration [Ljava.lang.Character; -> org.hibernate.type.CharacterArrayType@45196f3b
12:01:14,807 DEBUG BasicTypeRegistry:146 - Adding type registration Character[] -> org.hibernate.type.CharacterArrayType@45196f3b
12:01:14,808 DEBUG BasicTypeRegistry:146 - Adding type registration text -> org.hibernate.type.TextType@1dc59111
12:01:14,809 DEBUG BasicTypeRegistry:146 - Adding type registration ntext -> org.hibernate.type.NTextType@7c68b91c
12:01:14,813 DEBUG BasicTypeRegistry:146 - Adding type registration blob -> org.hibernate.type.BlobType@3ff3a808
12:01:14,813 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.Blob -> org.hibernate.type.BlobType@3ff3a808
12:01:14,814 DEBUG BasicTypeRegistry:146 - Adding type registration materialized_blob -> org.hibernate.type.MaterializedBlobType@1273544a
12:01:14,818 DEBUG BasicTypeRegistry:146 - Adding type registration clob -> org.hibernate.type.ClobType@7389a769
12:01:14,818 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.Clob -> org.hibernate.type.ClobType@7389a769
12:01:14,821 DEBUG BasicTypeRegistry:146 - Adding type registration nclob -> org.hibernate.type.NClobType@1e78a60e
12:01:14,822 DEBUG BasicTypeRegistry:146 - Adding type registration java.sql.NClob -> org.hibernate.type.NClobType@1e78a60e
12:01:14,822 DEBUG BasicTypeRegistry:146 - Adding type registration materialized_clob -> org.hibernate.type.MaterializedClobType@48e24332
12:01:14,823 DEBUG BasicTypeRegistry:146 - Adding type registration materialized_nclob -> org.hibernate.type.MaterializedNClobType@c556032
12:01:14,824 DEBUG BasicTypeRegistry:146 - Adding type registration serializable -> org.hibernate.type.SerializableType@47a89031
12:01:14,826 DEBUG BasicTypeRegistry:146 - Adding type registration object -> org.hibernate.type.ObjectType@4ae50837
12:01:14,827 DEBUG BasicTypeRegistry:146 - Adding type registration java.lang.Object -> org.hibernate.type.ObjectType@4ae50837
12:01:14,827 DEBUG BasicTypeRegistry:146 - Adding type registration imm_date -> org.hibernate.type.AdaptedImmutableType@35413a25
12:01:14,827 DEBUG BasicTypeRegistry:146 - Adding type registration imm_time -> org.hibernate.type.AdaptedImmutableType@4d506e73
12:01:14,828 DEBUG BasicTypeRegistry:146 - Adding type registration imm_timestamp -> org.hibernate.type.AdaptedImmutableType@5b8367ac
12:01:14,828 DEBUG BasicTypeRegistry:146 - Adding type registration imm_dbtimestamp -> org.hibernate.type.AdaptedImmutableType@100b7c24
12:01:14,828 DEBUG BasicTypeRegistry:146 - Adding type registration imm_calendar -> org.hibernate.type.AdaptedImmutableType@620327b6
12:01:14,828 DEBUG BasicTypeRegistry:146 - Adding type registration imm_calendar_date -> org.hibernate.type.AdaptedImmutableType@3d244fff
12:01:14,828 DEBUG BasicTypeRegistry:146 - Adding type registration imm_binary -> org.hibernate.type.AdaptedImmutableType@1b000db5
12:01:14,829 DEBUG BasicTypeRegistry:146 - Adding type registration imm_serializable -> org.hibernate.type.AdaptedImmutableType@2083f3ec
12:01:14,847  INFO Version:66 - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
12:01:14,853  INFO Version:54 - HHH000412: Hibernate Core {4.3.6.Final}
12:01:14,855  INFO Environment:239 - HHH000206: hibernate.properties not found
12:01:14,857  INFO Environment:346 - HHH000021: Bytecode provider name : javassist
12:01:15,199  INFO Dialect:145 - HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
12:01:15,343  INFO TransactionFactoryInitiator:62 - HHH000399: Using default transaction strategy (direct JDBC transactions)
12:01:15,348  INFO ASTQueryTranslatorFactory:47 - HHH000397: Using ASTQueryTranslatorFactory
12:01:15,369 TRACE TypeFactory:72 - Scoping types to session factory org.hibernate.internal.SessionFactoryImpl@250ea0db
12:01:15,561  INFO SchemaExport:343 - HHH000227: Running hbm2ddl schema export
Hibernate: drop table if exists student
Hibernate: create table student (STUDENT_ID integer not null, CIN varchar(8) not null, AGE integer, FIRST_NAME varchar(25) not null, LAST_NAME varchar(20) not null, MAIL varchar(30), PHONE varchar(20) not null, primary key (STUDENT_ID, CIN))
Hibernate: alter table student add constraint UK_lj69eor860a2au55t1v2srr90  unique (STUDENT_ID)
Hibernate: alter table student add constraint UK_eilt0rp8h8wnge0723nacyv84  unique (CIN)
12:01:16,313  INFO SchemaExport:405 - HHH000230: Schema export complete
12:01:16,405  INFO HibernateTransactionManager:339 - Using DataSource [org.apache.commons.dbcp2.BasicDataSource@78cbe299] of Hibernate SessionFactory for HibernateTransactionManager
12:01:16,514 ERROR BasicPropertyAccessor:121 - HHH000123: IllegalArgumentException in class: com.souhaieb.education.cursus.entities.Student, setter method of property: studentId
12:01:16,514 ERROR BasicPropertyAccessor:122 - HHH000091: Expected type: java.lang.Integer, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
12:01:16,524  INFO GenericApplicationContext:873 - Closing org.springframework.context.support.GenericApplicationContext@20a6a283: startup date [Fri Aug 15 12:01:14 GMT+01:00 2014]; root of context hierarchy

处理复合键有两个选项,一个是
EmbeddedId
,另一个是
IdClass

使用
EmbeddedId
时,您必须添加一个同时包含
Id
属性和
Student
实体的类,并用这个新类替换这两个属性。该类应该用
EmbeddedId
注释,并且在
Student
对象的属性中应该用
EmbeddedId
注释。检查是否有
EmbeddedId


我通常更喜欢使用
IdClass
,这样可以使对象保持干净,并且由于嵌入了类,不需要额外的间接寻址。为了使用它,我们刚刚用
IdClass
注释了
Student
类,该类提供了一个实现serializable并包含这两个属性的类,但是请记住,这个新类不需要任何hibernate注释。就这些了。请勾选此项,以获取有关
IdClass

为什么要使
studentId
自动递增的示例。主键用于唯一地标识行。如果您有studentId自动增量,则不需要复合键。@HiberKnight我对studentId的约束唯一性的看法是错误的,它一定不是唯一的。但在某些情况下,使用复合主键是必要的。