【问题标题】:LazyInitializationException encountered when using load instead of get with Hibernate在 Hibernate 中使用 load 而不是 get 时遇到 LazyInitializationException
【发布时间】:2012-05-25 19:29:19
【问题描述】:

我正在使用 JPA、Hibernate 和 Spring MVC。在控制器类中,所有方法都非常有效。当我在网络浏览器中测试它们时,public String getModuleFormation(long id) 方法返回一个对象,它给了我以下错误:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

作为根本原因,但昨天我试过了,它在 localhost:45045/GestionModules/detail/xx URL 中没有问题。

什么可能导致这个问题?

我的 detail.jsp:

<c:if test="${!empty detailModule}">

${detailModule.idModule}
${detailModule.libModule}
</c:if>

POJO 类 + JPA:

@Entity
@Table(name="ModuleFormation")
public class ModuleFormation {

private long idModule;
private String libModule;

public ModuleFormation() {
    // TODO Auto-generated constructor stub
}

public ModuleFormation(String libModule) {
    this.libModule = libModule;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "seqModule")
@SequenceGenerator(name="seqModule", sequenceName = "seqModuleFormation")
@Column(name="idModule")
public long getIdModule() {
    return this.idModule;
}

public void setIdModule(long idModule) {
    this.idModule = idModule;
}

@Column(name="libModule", nullable=false, length = 100)
public String getLibModule() {
    return this.libModule;
}

public void setLibModule(String libModule) {
    this.libModule = libModule;
}

}

DAO 类:

@Repository
public class ModuleFormationDAOImpl implements ModuleFormationDAO {

@Autowired
private SessionFactory sessionFactory;


public void ajouterModuleFormation(ModuleFormation module) {
    sessionFactory.getCurrentSession().save(module);
}

public void supprimerModuleFormation(long idModule) {
    ModuleFormation module = (ModuleFormation) sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule);
    if(module != null)
        sessionFactory.getCurrentSession().delete(module);
}

public List<ModuleFormation> listModuleFormation() {
    
    return sessionFactory.getCurrentSession().createQuery("from ModuleFormation")
            .list();
    
}

public ModuleFormation getModuleFormation(long idModule) {
     return (ModuleFormation) sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule);
}

public void majModuleFormation(ModuleFormation module) {
    sessionFactory.getCurrentSession().merge(module);
}

}

服务等级:

@Service
public class ModuleFormationServiceImpl implements ModuleFormationService {

@Autowired
private ModuleFormationDAO moduleDao;

@Transactional
public void ajouterModuleFormation(ModuleFormation module) {
    moduleDao.ajouterModuleFormation(module);
}

@Transactional
public void supprimerModuleFormation(long idModule) {
    moduleDao.supprimerModuleFormation(idModule);
}

@Transactional
public List<ModuleFormation> listModuleFormation() {
    return moduleDao.listModuleFormation();
}

@Transactional
public ModuleFormation getModuleFormation(long idModule) {
    return moduleDao.getModuleFormation(idModule);
}

@Transactional
public void majModuleFormation(ModuleFormation module) {
    moduleDao.majModuleFormation(module);
}
}

控制器类:

@Controller
public class ModuleFormationController {

@Autowired
private ModuleFormationService moduleService;

@RequestMapping("/module")
public String listModulesFormations(Map<String, Object> map) {
    
    map.put("module", new ModuleFormation());
    map.put("moduleList", moduleService.listModuleFormation());
    
    return "module";
}

@RequestMapping(value = "/ajouter", method = RequestMethod.POST )
public String ajouterModuleFormation(@ModelAttribute("module")
ModuleFormation module,BindingResult result) {
    
    moduleService.ajouterModuleFormation(module);
    
    return "redirect:/module";
}


@RequestMapping(value = "/supprimer/{idModule}")
public String supprimerModuleFormation(@PathVariable("idModule")
long idModule) {
    moduleService.supprimerModuleFormation(idModule);
    
    return "redirect:/module";
}


@RequestMapping(value= "/detail/{idModule}")
public String getModuleFormation(@PathVariable("idModule")
long idModule,Map<String, Object> map) {
    map.put("detailModule", moduleService.getModuleFormation(idModule));
    return "/detail";
}

    
@RequestMapping(value= "/detail/modifier", method = RequestMethod.POST )
public String majModuleFormation(@ModelAttribute("detailModule")
ModuleFormation module, BindingResult result) {
    moduleService.majModuleFormation(module);
    return "detail/{idModule}";
}

}

【问题讨论】:

    标签: java spring hibernate jsp


    【解决方案1】:

    Hibernate Session#load(Class, Serializable) 方法上的 Javadoc 说:

    返回具有给定标识符的给定实体类的持久实例, 假设实例存在。此方法可能会返回一个代理实例 在访问非标识符方法时按需初始化。

    当您在 JSP 中访问对象的属性时,加载该对象的会话已关闭。

    使用Session#get(Class, Serializable) 确保您不加载代理。

    【讨论】:

    • 没问题,但我认为您将错误答案标记为正确。另一个是在我之后发布的细节较少的副本。
    • 非常感谢!!!所以load的实体是延迟加载的,需要的时候会加载属性,但是当会话关闭时它不能加载它们。
    【解决方案2】:

    你试过sessionFactory.getCurrentSession().get(ModuleFormation.class, idModule)而不是sessionFactory.getCurrentSession().load(ModuleFormation.class, idModule)吗?

    【讨论】:

    • 正确,请参阅现有答案。
    猜你喜欢
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2017-11-21
    • 1970-01-01
    相关资源
    最近更新 更多