8_实现Serializable接口_重写equals和hashCode方法

控制台java application运行报错:

19:20:51,916  WARN RootClass:233 - composite-id class does not override equals(): com.mym.hibernate.model.StudentPK
(意思是:composite-id没有重写equals()方法,在com.num.hibernate.model.StudentPK)
Exception in thread "main" org.hibernate.MappingException: composite-id class must implement Serializable: com.mym.hibernate.model.StudentPK
(意思是:composite-id 必须实现Serializable接口,在com.mym.hibernate.model.StudentPK类中)
     at org.hibernate.mapping.RootClass.checkCompositeIdentifier(RootClass.java:243)
     at org.hibernate.mapping.RootClass.validate(RootClass.java:224)
     at org.hibernate.cfg.Configuration.validate(Configuration.java:1149)
     at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1334)
     at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
19:20:51,918  WARN RootClass:238 - composite-id class does not override hashCode(): com.mym.hibernate.model.StudentPK
(意思是:composite-id没有重写hashCode()方法,在com.num.hibernate.model.StudentPK)
     at com.mym.hibernate.model.StudentTest.beforeClass(StudentTest.java:16)
     at com.mym.hibernate.model.StudentTest.main(StudentTest.java:41)


控制台报错:

17:56:09,344  WARN RootClass:233 - composite-id class does not override equals(): com.mym.hibernate.model.StudentPK
17:56:09,346  WARN RootClass:238 - composite-id class does not override hashCode(): com.mym.hibernate.model.StudentPK

Junit报错:
org.hibernate.MappingException: composite-id class must implement Serializable: com.mym.hibernate.model.StudentPK
(意思是:composite-id 必须实现Serializable接口,在com.mym.hibernate.model.StudentPK类中)
    at org.hibernate.mapping.RootClass.checkCompositeIdentifier(RootClass.java:243)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:224)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1149)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1334)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at com.mym.hibernate.model.StudentTest.beforeClass(StudentTest.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

java.lang.NullPointerException
    at com.mym.hibernate.model.StudentTest.afterClass(StudentTest.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


我们先来看为什么要实现Serializable接口:

     这个接口的作用是将对象实现序列化,将数据变成数据流的形式,在网络、主机间进行传输,需要使用的时候,直接调用即可。跟EJB差不多,如果我们要实现java对象的序列化,就必须用到Serializable接口
     本例是在Student类的主键类中进行,而student类中的数据在内存中都是一个个对象,后期可能用到集群,好多台服务器对外提供服务,当有一台服务器down机了,需要将数据传到另外一台主机上,则需要实现序列化;还有可能如果将硬盘模拟成内存使用,将一部分对象暂时放入硬盘中,用到时再调用这些对象,也需要用到序列化。 在rmi和ejb使用的时候 作为参数传递的对象必须是serializable的
     综上所述,Student类的主键类需要实现序列化。


相关EJB的理解博文可以参考:http://blog.csdn.net/jojo52013145/article/details/5783677)
( a.EJB实现原理: 就是把原来放到客户端实现的代码放到服务器端,并依靠RMI进行通信。

b.RMI实现原理 :就是通过Java对象可序列化机制实现分布计算。

c.服务器集群: 就是通过RMI的通信,连接不同功能模块的服务器,以实现一个完整的功能 )

当我们实现Serializable接口后,再次出现了警告,说我们必须实现equals()和hashCode()方法:

19:33:13,613  WARN RootClass:233 - composite-id class does not override equals(): com.mym.hibernate.model.StudentPK
19:33:13,615  WARN RootClass:238 - composite-id class does not override hashCode(): com.mym.hibernate.model.StudentPK
19:33:14,084  INFO SchemaUpdate:155 - Running hbm2ddl schema update
19:33:14,085  INFO SchemaUpdate:167 - fetching database metadata
19:33:14,086  INFO SchemaUpdate:179 - updating schema
19:33:14,090  INFO DatabaseMetadata:119 - table not found: Student
19:33:14,114  INFO TableMetadata:65 - table found: hibernate._teacher
19:33:14,115  INFO TableMetadata:66 - columns: [zhicheng, id, title, birthdate, _name]
19:33:14,115  INFO TableMetadata:68 - foreign keys: []
19:33:14,115  INFO TableMetadata:69 - indexes: [primary]
19:33:14,117  INFO DatabaseMetadata:119 - table not found: Student
19:33:14,130  INFO TableMetadata:65 - table found: hibernate.generator_table
19:33:14,130  INFO TableMetadata:66 - columns: [pk_value, pk_key]
19:33:14,130  INFO TableMetadata:68 - foreign keys: []
19:33:14,131  INFO TableMetadata:69 - indexes: []
19:33:14,131 DEBUG SchemaUpdate:203 - create table Student (id integer not null, name varchar(255) not null, age integer, primary key (id, name))
19:33:14,187  INFO SchemaUpdate:217 - schema update complete
Hibernate:
    insert
    into
        Student
        (age, id, name)
    values
        (?, ?, ?)


为什么要实现equals()和hashCode()方法呢?
     我们知道,当我们在数据库中比较两个对象的不同,是通过主键来比较的,在内存中,我们也需要比较两个对象的不同,而判断不同的方法就是equals()和hashCode()方法。
     equals()方法用来判断主键id和主键name是否同时都相等,如果相等,则与此对象相等。
     hashCode()方法用来判定:当把对象装到一个hash表中,如果要查hash表里面的内容,必须首先对比这个对象的hashCode

     hash表:相当于一个数组,数组中有一个个位置,每一个位置都相当于一个链表,链表上装着hash码相同的对象, 如果有两个对象A和B,计算出他们的hash码,如果相同相同,则会被装在同一个位置,如果后期需要找到某一个对象,则会先计算出这个对象的hash码,然后直接找到hash表中hash码相同的位置,然后再遍历该位置上的对象,如果跟要找的对象equals,则表示找到对象。













你可能感兴趣的:(hibernate学习记录)