我编写了一个简单的Hibernate
程序,我对流程和构造函数的使用感到困惑。
这是主要的POJO课程:
package mypack;
import org.apache.log4j.Logger;
public class Emp {
String name,job;
int id,salary;
public Emp()
{
super();
System.out.println("Inside Default constructor"+this);
}
public Emp(String name, String job, int salary) {
super();
System.out.println("Inside parameterised constructor"+this);
this.name = name;
this.job = job;
this.salary = salary;
}
public String getName() {
System.out.println("Inside Get name"+this);
return name;
}
public void setName(String name) {
System.out.println("Inside set name"+this);
this.name = name;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
}
这是ObjectSaver
类:
package mypack;
import org.hibernate.*;
public class ObjSaver {
public static void main(String[] args) {
Emp e1=new Emp("A","job1",45000);
Emp e2=new Emp("B","Job2",45035);
Emp e3=new Emp("C","Job3",44585);
Emp e4=new Emp("4","Job4",44582545);
System.out.println("Saving Emp Objects");
Session session=Myfactory.getSession();
System.out.println("session obtained");
Transaction t1=session.beginTransaction();
System.out.println("Transaction begin");
session.save(e1);
session.save(e2);
session.save(e3);
session.save(e4);
t1.commit();
session.close();
System.out.println("Successfully Saved");
}
}
MyFactory
上课:
package mypack;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class Myfactory
{
private static SessionFactory factory;
static
{
System.out.println("Loading configuration...");
Configuration cfg=new Configuration().configure();
//Configuration cfg=new Configuration().configure("hibernate.cfg.xml");
System.out.println("Configuration loaded");
factory = cfg.buildSessionFactory();
System.out.println("SessionFactory Created");
}
public static Session getSession()
{
System.out.println("returning session");
return factory.openSession();
}
}
映射文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="mypack.Emp" table="Employee">
<id name="id" type="int">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="job"/>
<property name="salary"/>
</class>
</hibernate-mapping>
输出:
Inside parameterised constructormypack.Emp@1bab50a
Inside parameterised constructormypack.Emp@c3c749
Inside parameterised constructormypack.Emp@150bd4d
Inside parameterised constructormypack.Emp@1bc4459
Saving Emp Objects
Loading configuration...
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Configuration loaded
Inside Default constructormypack.Emp@fdb00d
Inside Default constructormypack.Emp$$EnhancerByCGLIB$$aa36f81a@17a4989
Inside Default constructormypack.Emp@659db7
Inside Get namemypack.Emp@659db7
Inside set namemypack.Emp@659db7
SessionFactory Created
returning session
session obtained
Transaction begin
Inside Get namemypack.Emp@1bab50a
Inside Get namemypack.Emp@c3c749
Inside Get namemypack.Emp@150bd4d
Inside Get namemypack.Emp@1bc4459
Inside Get namemypack.Emp@1bab50a
Inside Get namemypack.Emp@c3c749
Inside Get namemypack.Emp@150bd4d
Inside Get namemypack.Emp@1bc4459
Inside Get namemypack.Emp@150bd4d
Inside Get namemypack.Emp@c3c749
Inside Get namemypack.Emp@1bc4459
Inside Get namemypack.Emp@1bab50a
Hibernate: insert into Employee (name, job, salary, id) values (?, ?, ?, ?)
Hibernate: insert into Employee (name, job, salary, id) values (?, ?, ?, ?)
Hibernate: insert into Employee (name, job, salary, id) values (?, ?, ?, ?)
Hibernate: insert into Employee (name, job, salary, id) values (?, ?, ?, ?)
Successfully Saved
为什么默认构造函数运行三次?为什么setter和getter只是在默认的构造函数之后运行?任何人都可以解释这个流程吗?
答案 0 :(得分:0)
Hibernate
要求所有持久化类的无参数构造函数。
因为Hibernate
使用Java Reflection(为默认构造函数调用)为您创建对象,所以将使用save方法为您持久保存的每个对象调用默认构造函数。
Hibernate
使用setter方法在您从数据库读取数据时初始化实体,并使用getter方法在持久保存到DB时保持实际值。
由于你只是坚持,所以应该只调用getter。
答案 1 :(得分:0)
根据您发布的日志,在SessionFactory引导时调用构造函数。当Hibernate启动时,它会实例化您的实体,以确定应使用哪个值来表示标识符属性的未保存(默认)值。我想这可能会发生多次,基于Hibernate用于映射的实体持久性。这将有助于获得有关您的确切映射的更多信息,以了解为什么会发生这种情况三次。如果您真正感兴趣,可以跟踪以下代码:
org.hibernate.engine.UnsavedValueFactory.getUnsavedIdentifierValue(...)
或者只是在构造函数中设置一个断点。