我有三个实体,比如A,B和C. A包含B和C的多个实例。从逻辑上讲,从A到B和A到C将有两个一对多的关系。行正在增加填充在表中,但B和C在外键列中没有A的ID。代码如下:
A类:
@Entity
public class A
{
private int id;
private B[] bSet = null;
private C[] cSet = null;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getId()
{return id;}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a")
@OrderColumn(name = "bIndex")
public B[] getBset()
{return bSet;}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a")
@OrderColumn(name = "cIndex")
public C[] getCset()
{return cSet;}
}
B组:
@Entity
public class B
{
private int bId;
private A a;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getBId()
{return bId;}
@ManyToOne(cascade = CascadeType.ALL)
public A getA(A a)
{return a;}
}
C类:
@Entity
public class C
{
private int cId;
private A a;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public int getCId()
{return cId;}
@ManyToOne(cascade = CascadeType.ALL)
public A getA(A a)
{return a;}
}
您可能会问为什么我也在A中设置OneToMany端的级联属性。但如果我不这样做,它会引发像这样的瞬态对象异常。
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: B
如果我这样做,异常消失,数据保存在H2数据库中,但B和C中的A列都获取空值。请帮帮我。
修改
我在这里添加了用于持久保存实体的方法。出于我的目的,我使所有实体都从一个普通的空类扩展,以便于使用。
public void populateObjects()
{
HashMap<String,ArrayList<HibernateEntity>> persistentEntities = new HashMap<String, ArrayList<HibernateEntity>>();
persistentEntities.put("A", new ArrayList<HibernateEntity>());
persistentEntities.put("B", new ArrayList<HibernateEntity>());
persistentEntities.put("C", new ArrayList<HibernateEntity>());
A a = new A();
a.bSet = new B[2];
a.bSet[0] = new B();
a.bSet[1] = new B();
a.cSet = new C[1];
a.cSet[0] = new C();
persistentEntities.get("A").add(a);
start();
persistEntities(persistentEntities);
}
public synchronized boolean start() throws Exception
{
if(isStarted)
return isStarted;
server = Server.createTcpServer();
server.start();
Properties prop = new Properties();
String propFileName = "database.properties";
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);
prop.load(inputStream);
if(inputStream == null)
{
throw new FileNotFoundException("Property file "+propFileName+" not found in classpath");
}
String dbPath = prop.getProperty("db_path");
String dbName = prop.getProperty("db_name");
System.out.println("Full database path: "+"jdbc:h2:file:"+dbPath+dbName);
DriverManager.getConnection("jdbc:h2:file:"+dbPath+dbName);
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
isStarted = true;
return isStarted;
}
public void persistEntities(HashMap<String, ArrayList<HibernateEntity>> persistentEntities)
{
Session session = openSession();
Transaction transaction = session.beginTransaction();
Set<String> keySet = persistentEntities.keySet();
try
{
for(String key: keySet)
{
ArrayList<HibernateEntity> entities = persistentEntities.get(key);
if(key.equalsIgnoreCase("A"))
{
if(entities.size() > 0)
{
for(HibernateEntity h: entities)
{
A a = (A)h;
session.save(a);
}
}
}
else if(key.equalsIgnoreCase("B"))
{
if(entities.size() > 0)
{
for(HibernateEntity h: entities)
{
session.save((B)h);
System.out.println("Persisted "+key);
}
}
}
else if(key.equalsIgnoreCase("C"))
{
if(entities.size() > 0)
{
for(HibernateEntity h: entities)
{
session.save((C)h);
System.out.println("Persisted "+key);
}
}
}
}
transaction.commit();
System.out.println("Successfully committed");
}
finally
{
closeSession(session);
}
}