这是我的代码段:
public class Object1 implements Serializable {
@Id
@Column(length = 36)
protected String id;
@Column(length = 36, insertable = false, updatable = false)
protected String parentID;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "object2ID", referencedColumnName = "parentID")
protected List<Object2> parents = new ArrayList<>();
public List<Object2> getParents() {
return parents;
}
}
public class Object2 implements Serializable {
@Id
@Column(length = 36)
protected String id;
@Column(length = 36, insertable = false, updatable = false)
protected String object2ID;
@Column(length = 36, insertable = false, updatable = false)
protected String parentID;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "object2ID", referencedColumnName = "parentID")
protected List<Object2> parents = new ArrayList<>();
public List<Object2> getParents() {
return parents;
}
}
和应用程序类:
public class Application {
public static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
Path HIBERNATE_CONFIGURATION = Paths.get("");
Configuration configuration = new Configuration().configure(HIBERNATE_CONFIGURATION.toFile());
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
Object1 object1 = (Object1) session.get(Object1.class, "1");
logger.info(object1.toString());
Object2 object2 = object1.getParents().get(0);
logger.info(object2.toString());
while (!object2.getParents().isEmpty()) {
object2 = object2.getParents().get(0);
logger.info(object2.toString());
}
session.close();
}
}
我按预期获得了Object1,但是object2抛出异常org.hibernate.LazyInitializationException: could not initialize proxy - no Session
会话未关闭,为什么我收到此错误?
我使用的是Hibernate核心:4.3.7.Final
解决:
您好。谢谢大家。我发现解决了我的问题。我尝试获取OneToMany,但在db引用中实际是类型ManyToMany。我为db和model创建了一些小改动。
我重命名对象。 这是新的代码段:
@Entity
@Table(name = "Houses")
public class House implements Serializable {
@Id
@Column(length = 36)
protected String id;
@Column(length = 36)
protected String parentGUID;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentguid", referencedColumnName = "guid")
protected AddressObject address;
public AddressObject getAddress() {
return address;
}
@Override
public String toString() {
return "Object1{" +
"id='" + id + '\'' +
", parentGUID='" + parentGUID + '\'' +
'}';
}
}
@Entity
@Table(name = "AddressObjects")
public class AddressObject implements Serializable {
@Id
@Column(length = 36)
protected String id;
@Column(length = 36, unique = true)
protected String guid;
@Column(length = 36, nullable = true)
protected String parentGUID;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "address")
protected List<House> houses = new ArrayList<>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "upHierarchicObject")
protected List<AddressObject> downHierarchicObject = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentguid", referencedColumnName = "guid")
protected AddressObject upHierarchicObject;
public List<House> getHouses() {
return houses;
}
public List<AddressObject> getDownHierarchicObject() {
return downHierarchicObject;
}
public AddressObject getUpHierarchicObject() {
return upHierarchicObject;
}
@Override
public String toString() {
return "Object2{" +
"id='" + id + '\'' +
", guid='" + guid + '\'' +
", parentGUID='" + parentGUID + '\'' +
'}';
}
}
和应用程序类:
public class Application {
public static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ArrayList<Object> objects = new ArrayList<>();
Path HIBERNATE_CONFIGURATION = Paths.get("config/hibernate.test.cfg.xml");
Configuration configuration = new Configuration().configure(HIBERNATE_CONFIGURATION.toFile());
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Session session = sessionFactory.openSession();
House house = (House) session.get(House.class, "1");
objects.add(house);
AddressObject addressObject = house.getAddress();
objects.add(addressObject);
while (addressObject.getUpHierarchicObject() != null) {
addressObject = addressObject.getUpHierarchicObject();
objects.add(addressObject);
}
for (Object obj : objects) {
logger.info("Object: {}", obj);
}
session.close();
}
}
但是,除了LazyInitializationException,我不知道为什么。这是hibernate的一个错误吗?
答案 0 :(得分:0)
懒惰就是你忘了在查询中进行提取(这里是为了父母),你试图在关闭会话后检索java对象 在代码的这一部分中,您如何知道来自object1的object2是通过Parents获取的? 这里我们只测试null
object1.getParents() != null
但是在惰性的情况下,对象不是null而是虚拟
如果要使用它,则需要打开会话 但在此步骤中会话已经关闭 因为我们在从数据库中重新获取对象后立即关闭会话
示例:
Session s = sessions.openSession();
Transaction tx = s.beginTransaction();
Employee e = (Employee) s.createQuery("from Employee e where e.name=:empName").setString("empName", eName).uniqueResult();
List roles = u.getRoles();
tx.commit();
s.close();
String role = roles.get(0); // This line will throw error
Easy Solution
Use lazy=false in your Entity class.
注意强>
此处会话未关闭。这可以做到这一点
获取条件可以在Entity类的多对一条件中执行 fetch =&#34; join&#34; 或 FetchMode.JOIN 的技巧 映射中定义的获取策略会影响:
retrieval via get()
希望这有帮助。
答案 1 :(得分:-1)
您必须提供虚拟循环才能首先获取所有对象。
例如
for (Object2 obj:object1.getParents()) {
obj.getName();
}