Spring JPA Lazy Loading - Could Not Initialize Proxy - java

Below is some code for background:
InitiativeProfileQuestion.java:
#Entity
#Table
public class InitiativeProfileQuestion implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(nullable = false)
private String question;
#Column
private String description;
#Column
private int sortOrder;
#OneToMany(mappedBy = "initiativeProfileQuestion", fetch = FetchType.LAZY)
private List<InitiativeProfileAnswer> answers;
public List<InitiativeProfileAnswer> getAnswers() {
return answers;
}
public void setAnswers(List<InitiativeProfileAnswer> answers) {
this.answers = answers;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getSortOrder() {
return sortOrder;
}
public void setSortOrder(int sortOrder) {
this.sortOrder = sortOrder;
}
}
InitiativeProfileAnswer.java:
#Entity
#Table
public class InitiativeProfileAnswer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column
private String answer;
#Column
private int sortOrder;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "initiativeProfileQuestionId")
#JsonIgnore
private InitiativeProfileQuestion initiativeProfileQuestion;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public int getSortOrder() {
return sortOrder;
}
public void setSortOrder(int sortOrder) {
this.sortOrder = sortOrder;
}
public InitiativeProfileQuestion getInitiativeProfileQuestion() {
return initiativeProfileQuestion;
}
public void setInitiativeProfileQuestion(InitiativeProfileQuestion initiativeProfileQuestion) {
this.initiativeProfileQuestion = initiativeProfileQuestion;
}
}
InitiativeProfileQuestionRepository.java:
public interface InitiativeProfileQuestionRepository extends JpaRepository<InitiativeProfileQuestion, Long> {
#Query("select ipa from InitiativeProfileQuestion ipa join fetch ipa.answers")
public List<InitiativeProfileQuestion> getAllQuestions();
}
InitiativeProfileService.java:
#Service
public class InitiativeProfileService {
#Autowired
private InitiativeProfileQuestionRepository initiativeProfileQuestionRepository;
public List<InitiativeProfileQuestion> getAllQuestions() {
return initiativeProfileQuestionRepository.findAll();
}
public List<InitiativeProfileQuestion> getAllQuestionsFetch() {
return initiativeProfileQuestionRepository.getAllQuestions();
}
}
BaseController.java:
#RestController
#RequestMapping("/api")
public class BaseController {
#Autowired
InitiativeProfileService initiativeProfileService;
#RequestMapping("/question")
public List<InitiativeProfileQuestion> getQuestions() {
return initiativeProfileService.getAllQuestions();
}
#RequestMapping("/questionFetch")
public List<InitiativeProfileQuestion> getQuestionsFetch() {
return initiativeProfileService.getAllQuestionsFetch();
}
}
Calling getQuestions() in my BaseController returns a "could not initialize proxy - no Session" error. However, calling getQuestionsFetch() in my BaseController loads just fine.
I want it to work in a way that if I call getQuestions(), the object will be returned with NO answers (since the lazy loaded object will not be called anywhere). However, it just gives me an error. If I'm doing a query with a join fetch, it works by showing the answers as well (expected behavior).
What am I doing wrong? I tried #Transactional in different places with no luck. I also have no .xml files- everything so far is done using annotations.
The error I get is:
exception
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: failed to lazily initialize a collection of role: com.testApp.domain.InitiativeProfileQuestion.answers, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.testApp.domain.InitiativeProfileQuestion["answers"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.testApp.domain.InitiativeProfileQuestion.answers, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.testApp.domain.InitiativeProfileQuestion["answers"])
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:238)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:161)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:185)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
root cause
com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.testApp.domain.InitiativeProfileQuestion.answers, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.testApp.domain.InitiativeProfileQuestion["answers"])
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210)
com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:177)
com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:187)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:647)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase._serializeWithObjectId(BeanSerializerBase.java:558)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:145)
com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:100)
com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:21)
com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:183)
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:128)
com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1902)
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231)
org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:161)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101)
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:185)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

For an exception in case of lazy loading you must be trying to fetch the associated objects outside the session. Either change the lazy loading to eager or put your code which is fetching the associated object inside the session.
For e.g:
public void test() {
Session session = HibernateUtil.currentSession();
session.beginTransaction();
Vehicle vehicle= (Vehicle) session.get(Vehicle.class, 2);
System.out.println(vehicle.getVehicleName());
session.getTransaction().commit();
session.close();
System.out.println(vehicle.getVehicleName()); //No exception here
System.out.println(vehicle.getUser().getUserName());
// Exception here change the loading to EAGER or put this line of code within the session above. Put it before session.close() or before session.getTransaction().commit();
}

As you can see from the stacktrace, the error occurs when Jackson is trying to access the lazily loaded object in order to serialize it to JSON. At this time, the spring transaction has already completed, and the Hibernate session closed, which is why Hibernate can no longer load that object.
If you do not intend that field to be serialized, you might wish to use #JsonIgnore, or Spring's Jackson Serialization View Support.

Related

Hibernate is not mapping new attribute on the class

I'm following some tutorials on Hibernate and at a certain point i need to add a new attribute to a class called Produto. It should be no problem since I've done it before and had no issues, but the thing is that when I restart the server, the framework seems to be missing the added field and doesn't add it to the database table, therefore I get erros when I'm trying to use the attribute on my JSP.
the Class:
#Entity
public class Produto {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#NotEmpty
private String nome;
#NotEmpty
private String linkDaFoto;
#NotEmpty
#Column(columnDefinition="TEXT")
private String descricao;
#Min(20)
private double preco;
#ManyToMany
private List<Categoria> categorias = new ArrayList<>();
#Version
private int versao;
public int getVersao() {
return versao;
}
public void setVersao(int versao) {
this.versao = versao;
}
public List<Categoria> getCategorias() {
return categorias;
}
public void setCategorias(List<Categoria> categorias) {
this.categorias = categorias;
}
#Valid
#ManyToOne
private Loja loja;
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
//método auxiliar para associar categorias com o produto
//se funcionar apos ter definido o relacionamento entre produto e categoria
public void adicionarCategorias(Categoria... categorias) {
for (Categoria categoria : categorias) {
this.categorias.add(categoria);
}
}
public String getLinkDaFoto() {
return linkDaFoto;
}
public double getPreco() {
return preco;
}
public void setPreco(double preco) {
this.preco = preco;
}
public void setLinkDaFoto(String linkDaFoto) {
this.linkDaFoto = linkDaFoto;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setLoja(Loja loja) {
this.loja = loja;
}
public Loja getLoja() {
return loja;
}
}
The Error:
org.apache.jasper.JasperException: javax.el.PropertyNotFoundException: Property [versao] not found on type [br.com.caelum.model.Produto]
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:638)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:514)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
javax.el.PropertyNotFoundException: Property [versao] not found on type [br.com.caelum.model.Produto]
javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:260)
javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:212)
javax.el.BeanELResolver.property(BeanELResolver.java:347)
javax.el.BeanELResolver.getValue(BeanELResolver.java:92)
org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:113)
org.apache.el.parser.AstValue.getValue(AstValue.java:169)
org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:702)
org.apache.jsp.WEB_002dINF.views.produto.form_jsp._jspService(form_jsp.java:379)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Add hibernate.hbm2ddl.auto=update to your property file and restart the application. Hibernate should create the column for you automatically.
I think you must to clean the server from loaded data. Before a few weeks I have the same problem and when I cleaned the resources the problem was solved.

a hibernate LazyInitializationException which is very trick

I have two piece of code segments, they are almost exactly the same, except their locations are different, one locates in RestLoginDLCtrl(a controller) the other locates in CouponManagerController(a controller).But one code segment is right, the other one throws org.hibernate.LazyInitializationException.
I know how to solve my problem. confused me the most is why one is OK the other is wrong, but they are almost the same code. why? Any help would be appreciate.
ConversionCode is a value object which has a set named codeRewards and managerService is a service class.
note:
Finally, I found some interesting phenomena. when I use ajax way to post the http request, two methods both well:
$.ajax({
type: "POST",
url: "/CouponInfo/useConversionCode.do",
data: {
code: key
},
dataType: "json",
success: function (data) {
}
});
But when I use form way, two methods both did not work:Does hibernate lazy initialize mechnism has relationship with http request way?
<form action=""></form>
The CouponManagerController controller class:
#Controller
#RequestMapping(value = "${adminPath}/CouponInfo")
public class CouponManagerController extends RestBaseCtrl {
#Autowired
CouponManagerService managerService;
#ResponseBody
public void useConversionCode(String code, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/json;charset=utf-8");
try {
LoginCustInfo info = (LoginCustInfo) request.getSession().getAttribute(SystemProperties.DUOLIJR_LOGIN_USER);
ConversionCode conversionCode = managerService.queryConversionCodeByCode(code);
if (conversionCode != null) {
managerService.useConversionCode(conversionCode, info.getCustId());
response.getWriter().print("[{\"success\":\"true\",\"message\":\"兑换成功\"}]");
} else {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"无效兑换码\"}]");
}
} catch (ParseException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The RestLoginDLCtrl controller class:
#Controller
#RequestMapping(value = "${adminPath}/yqxqrest/loginDLCtrl", method = RequestMethod.POST)
public class RestLoginDLCtrl extends RestBaseCtrl {
#Autowired
CouponManagerService managerService;
#RequestMapping(value = "useConversionCode")
#ResponseBody
public void useConversionCode(String code, HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/json;charset=utf-8");
try {
LoginCustInfo info = (LoginCustInfo) request.getSession().getAttribute(SystemProperties.DUOLIJR_LOGIN_USER);
ConversionCode conversionCode = managerService.queryConversionCodeByCode(code);
if (conversionCode != null) {
managerService.useConversionCode(conversionCode, info.getCustId());
response.getWriter().print("[{\"success\":\"true\",\"message\":\"兑换成功\"}]");
} else {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"无效兑换码\"}]");
}
} catch (ParseException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
try {
response.getWriter().print("[{\"success\":\"false\",\"message\":\"兑换失败!请稍后重试!\"}]");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The CouponManagerServiceImpl service class:
#Service("ActivitiesCouponsService")
public class CouponManagerServiceImpl extends BaseServiceImpl implements CouponManagerService {
#Autowired
JdbcDao jdbcDao;
#Autowired
ActivitiesCouponsService couponsService;
#Override
public ConversionCode queryConversionCodeByCode(String code){
ConversionCode conversionCode=null;
String hql = " from ConversionCode where DELETE_FLAG=0 and state=0 and code='"+code+"'";
List<ConversionCode> codes = jdbcDao.find(hql);
if (codes.size()>0) {
conversionCode=codes.get(0);
}
return conversionCode;
}
/**
* 使用兑换码
* #param conversionCode
* #param custId
* #throws ParseException
*/
#Override
public void useConversionCode(ConversionCode conversionCode,Integer custId) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date now = new Date();
Calendar endTime = Calendar.getInstance();
endTime.setTime(sdf.parse(sdf.format(now)));
Set<ConversionCodeReward> codeRewards=conversionCode.getCodeRewards();
StringBuffer sb=new StringBuffer();
String a="";
for(ConversionCodeReward codeReward:codeRewards) {
CustActivitiesInfo activitiesInfo = new CustActivitiesInfo();
activitiesInfo.setCustId(custId);
activitiesInfo.setCouponsType(codeReward.getCouponsType());
String couponsName=couponsService.findUcTypeDictionaryBycode("COUPONS_TYPE", codeReward.getCouponsType() + "").getItemName();
activitiesInfo.setCouponsName(couponsName);
activitiesInfo.setActivitiesAmount(codeReward.getActivitiesAmount());
endTime.add(Calendar.DAY_OF_YEAR, Integer.valueOf(codeReward.getValidPeriod()));
endTime.add(Calendar.SECOND, -1);
activitiesInfo.setStartDate(sdf.parse(sdf.format(now)));
activitiesInfo.setEndDate(endTime.getTime());
activitiesInfo.setTaskAction("兑换码");
activitiesInfo.setUseMeetAmount(codeReward.getUseMeetAmount());
activitiesInfo.setUsePlanType(codeReward.getUsePlanType());
activitiesInfo.setUsePlanPeriod(codeReward.getUsePlanPeriod());
activitiesInfo.setState(1);
jdbcDao.saveObject(activitiesInfo);
sb.append("1张"+codeReward.getCouponsName()+"、");
}
conversionCode.setState(1);
jdbcDao.updateObject(conversionCode);
}
}
The ConversionCode value object class:
#Entity
#Table(name = "conversion_code")
public class ConversionCode extends BaseEntity implements java.io.Serializable{
private int id;
private String code;
private Date endDate;
private int state;
private String remark;
private Set<ConversionCodeReward> codeRewards;
public ConversionCode(int id,String code,Date endDate,int state,String remark){
super();
this.id=id;
this.code=code;
this.endDate=endDate;
this.state=state;
this.remark=remark;
}
public ConversionCode(){
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name = "end_date")
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
#Column(name = "state")
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
#ManyToMany(fetch=FetchType.LAZY,mappedBy="codes")
public Set<ConversionCodeReward> getCodeRewards() {
return codeRewards;
}
public void setCodeRewards(Set<ConversionCodeReward> codeRewards) {
this.codeRewards = codeRewards;
}
#Column(name = "remark")
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
The ConversionCodeReward value object class:
#Entity
#Table(name = "conversion_code_reward")
public class ConversionCodeReward extends BaseEntity implements java.io.Serializable{
private Integer id;
private String couponsName;
private int couponsType;
private double activitiesAmount;
private int validPeriod;
private double useMeetAmount;
private String usePlanType;
private int usePlanPeriod;
private Set<ConversionCode> codes;
public ConversionCodeReward(Integer id,String couponsName,int couponsType,double activitiesAmount,
int validPeriod,double useMeetAmount,String usePlanType,int usePlanPeriod){
super();
this.id=id;
this.couponsName=couponsName;
this.couponsType=couponsType;
this.activitiesAmount=activitiesAmount;
this.validPeriod=validPeriod;
this.useMeetAmount=useMeetAmount;
this.usePlanType=usePlanType;
this.usePlanPeriod=usePlanPeriod;
}
public ConversionCodeReward(){
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "coupons_name")
public String getCouponsName() {
return couponsName;
}
public void setCouponsName(String couponsName) {
this.couponsName = couponsName;
}
#Column(name = "coupons_type")
public int getCouponsType() {
return couponsType;
}
public void setCouponsType(int couponsType) {
this.couponsType = couponsType;
}
#Column(name = "activities_amount")
public double getActivitiesAmount() {
return activitiesAmount;
}
public void setActivitiesAmount(double activitiesAmount) {
this.activitiesAmount = activitiesAmount;
}
#Column(name = "valid_period")
public int getValidPeriod() {
return validPeriod;
}
public void setValidPeriod(int validPeriod) {
this.validPeriod = validPeriod;
}
#Column(name = "use_meet_amount")
public double getUseMeetAmount() {
return useMeetAmount;
}
public void setUseMeetAmount(double useMeetAmount) {
this.useMeetAmount = useMeetAmount;
}
#Column(name = "use_planType")
public String getUsePlanType() {
return usePlanType;
}
public void setUsePlanType(String usePlanType) {
this.usePlanType = usePlanType;
}
#Column(name = "use_planPeriod")
public int getUsePlanPeriod() {
return usePlanPeriod;
}
public void setUsePlanPeriod(int usePlanPeriod) {
this.usePlanPeriod = usePlanPeriod;
}
#ManyToMany(cascade={CascadeType.MERGE,CascadeType.REFRESH},fetch=FetchType.LAZY)
#JoinTable(name = "code_and_reward",
joinColumns = { #JoinColumn(name = "reward_id") },
inverseJoinColumns = { #JoinColumn(name = "code_id") })
#Where(clause="DELETE_FLAG=0")
public Set<ConversionCode> getCodes() {
return codes;
}
public void setCodes(Set<ConversionCode> codes) {
this.codes = codes;
}
}
The stack trace of the exception:
2015-12-16 15:38:34,059 ERROR (org.hibernate.LazyInitializationException:19) - failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
at com.yqxqfront.coupon.service.impl.CouponManagerServiceImpl.useConversionCode(CouponManagerServiceImpl.java:152)
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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
at com.yiqixiangqian.common.log.LogAspect.around(LogAspect.java:31)
at sun.reflect.GeneratedMethodAccessor255.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy119.useConversionCode(Unknown Source)
at com.yqxqfront.rest.controller.RestLoginDLCtrl.useConversionCode(RestLoginDLCtrl.java:665)
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.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:144)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.yqxqfront.rest.filter.SessionFilter.doFilter(SessionFilter.java:186)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.yqxqfront.filter.ImageVerifyCodeFilter.doFilter(ImageVerifyCodeFilter.java:66)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:615)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1774)
at java.lang.Thread.run(Thread.java:662)
Hibernate: select custmessag0_.UID as UID245_, custmessag0_.CREATE_DATE as CREATE2_245_, custmessag0_.CREATED_BY as CREATED3_245_, custmessag0_.DELETE_FLAG as DELETE4_245_, custmessag0_.LAST_UPDATE_DATE as LAST5_245_, custmessag0_.UPDATE_BY as UPDATE6_245_, custmessag0_.VERSION as VERSION245_, custmessag0_.CONTENT as CONTENT245_, custmessag0_.CUST_ID as CUST9_245_, custmessag0_.ISCHECK as ISCHECK245_, custmessag0_.PUB_DATE as PUB11_245_, custmessag0_.TITLE as TITLE245_, custmessag0_.TYPE as TYPE245_ from cust_message custmessag0_ where custmessag0_.CUST_ID=? and custmessag0_.ISCHECK=? and custmessag0_.DELETE_FLAG=0
failed to lazily initialize a collection of role: com.yiqixiangqian.entity.ConversionCode.codeRewards, no session or session was closed
The useConversionCode() method which locates in CouponManagerController controller is OK:
The useConversionCode() method which locates in RestLoginDLCtrl controller is wrong and throws a LazyInitializationException exception:
Finally, I found some interesting phenomena. when I use ajax way to post the http request, two methods both well:
$.ajax({
type: "POST",
url: "/CouponInfo/useConversionCode.do",
data: {
code: key
},
dataType: "json",
success: function (data) {
}
});
but when I use form way, two methods both did not work:
<form action=""></form>
Does hibernate lazy initialize mechnism has relationship with http request way?
I know how this issue occured.Suddenly, I found there is a OpenSessionInViewFilter in the web.xml file.
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
In my form post request way, I did not add the .do request suffix, so the OpenSessionInViewFilter did not work, so the LazyInitializationException occured.
But the ajax post request way added the .do request suffix, so the OpenSessionInViewFilter worked and LazyInitializationException did not occur.

Error while Inserting into many to many relationship using hibernate

I am trying to insert into many to many relationship using hibernate but I am getting this error.
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
Apr 24, 2014 2:55:25 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet applicationController threw exception
java.lang.IllegalArgumentException: java.lang.ClassCastException#17d66f6
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Here is the code that I am trying.
VehicleProduct class
#Entity
#Table(name="m_vehicle_product")
#AssociationOverrides({
#AssociationOverride(name = "pk.vehicle",
joinColumns = #JoinColumn(name = "vehicle_id")),
#AssociationOverride(name = "pk.product",
joinColumns = #JoinColumn(name = "product_id")),
})
public class VehicleProduct extends AbstractEntity{
private String service;
private VehicleProductId pk = new VehicleProductId();
#Column(name = "service")
public String getService() {
return service;
}
public void setService(String service) {
this.service = service;
}
#EmbeddedId
public VehicleProductId getPk() {
return pk;
}
public void setPk(VehicleProductId pk) {
this.pk = pk;
}
#Transient
public Product getProduct(){
return getPk().getProduct();
}
public void setProduct(Product product){
getPk().setProduct(product);
}
#Transient
public Vehicle getVehicle(){
return getPk().getVehicle();
}
public void setVehicle(Vehicle vehicle){
getPk().setVehicle(vehicle);
}
}
VehicleProductId Class
#Embeddable
public class VehicleProductId implements java.io.Serializable {
private Vehicle vehicle;
private Product product;
#ManyToOne
public Vehicle getVehicle() {
return vehicle;
}
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
#ManyToOne
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}
And this is how I am Inserting.
for(int i=0;i<jobid.length;i++){
product = productService.findByPkey(jobid[i]);
vehicleProduct.setProduct(product);
vehicleProduct.setService(jobdesc[i]);
pkey2 = vehicleProductService.save(vehicleProduct);
}
Please guide me on this. Trying since hours to solve this problem.
EDIT
#MappedSuperclass
public class AbstractEntity implements IEntity, Serializable{
private static final long serialVersionUID = 1L;
private Long pkey;
private Boolean deleted;
private String creator;
private Date created;
private String changer;
private Date changed;
private Long version;
#Id
#GeneratedValue
#Column(name="pkey")
public Long getPkey() {
return pkey;
}
public void setPkey(Long pkey) {
this.pkey = pkey;
}
#Column(name="deleted")
#XmlTransient
public Boolean getDeleted() {
return deleted;
}
public void setDeleted(Boolean deleted) {
this.deleted = deleted;
}
#Column(name="creator")
public String getCreator() {
return creator;
}
}........
It contains all of these getter and setters.
Your main problem is this:
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
If you look at your code, you have an #Id defined on your AbstractEntity and an #EmbeddedId on your VehicleProduct
I am not sure how your database table is supposed to look, but it will seem to include the columns in AbstractEntity as well as those defined in VehicleProduct. If the columns are not meant to be there, then you shouldn't inherit from AbstractEntity. If they were meant to be there, then consider making the #EmbeddedId into an #Embedded and enforce a unique constraint for the business key.
2014-04-24 14:50:47,820 ERROR [BasicPropertyAccessor.java:118] : IllegalArgumentException in class: com.jellboi.maniartyre.entities.AbstractEntity, setter method of property: pkey
2014-04-24 14:50:47,827 ERROR [BasicPropertyAccessor.java:122] : expected type: java.lang.Long, actual value: org.hibernate.id.IdentifierGeneratorHelper$2
I do not know it this is your case, but taking a look to your trace I have to say hibernate does not support composite PK's with an identity part
Hibernate Jira composite PK identity part

How to fix Hibernate LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session

In the custom AuthenticationProvider from my spring project, I am trying read the list of authorities of the logged user, but I am facing the following error:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.horariolivre.entity.Usuario.autorizacoes, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266)
at com.horariolivre.security.CustomAuthenticationProvider.authenticate(CustomAuthenticationProvider.java:45)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Reading other topics from here in StackOverflow, I understand this happens due the way this type of atribute is handled by the framework, but i can't figure out any solution for my case. Someone can point what i am doing wrong and what I can do to fix it?
The code of my Custom AuthenticationProvider is:
#Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
#Autowired
private UsuarioHome usuario;
public CustomAuthenticationProvider() {
super();
}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
System.out.println("CustomAuthenticationProvider.authenticate");
String username = authentication.getName();
String password = authentication.getCredentials().toString();
Usuario user = usuario.findByUsername(username);
if (user != null) {
if(user.getSenha().equals(password)) {
List<AutorizacoesUsuario> list = user.getAutorizacoes();
List <String> rolesAsList = new ArrayList<String>();
for(AutorizacoesUsuario role : list){
rolesAsList.add(role.getAutorizacoes().getNome());
}
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role_name : rolesAsList) {
authorities.add(new SimpleGrantedAuthority(role_name));
}
Authentication auth = new UsernamePasswordAuthenticationToken(username, password, authorities);
return auth;
}
else {
return null;
}
} else {
return null;
}
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
My Entity classes are:
UsuarioHome.java
#Entity
#Table(name = "usuario")
public class Usuario implements java.io.Serializable {
private int id;
private String login;
private String senha;
private String primeiroNome;
private String ultimoNome;
private List<TipoUsuario> tipoUsuarios = new ArrayList<TipoUsuario>();
private List<AutorizacoesUsuario> autorizacoes = new ArrayList<AutorizacoesUsuario>();
private List<DadosUsuario> dadosUsuarios = new ArrayList<DadosUsuario>();
private ConfigHorarioLivre config;
public Usuario() {
}
public Usuario(String login, String senha) {
this.login = login;
this.senha = senha;
}
public Usuario(String login, String senha, String primeiroNome, String ultimoNome, List<TipoUsuario> tipoUsuarios, List<AutorizacoesUsuario> autorizacoesUsuarios, List<DadosUsuario> dadosUsuarios, ConfigHorarioLivre config) {
this.login = login;
this.senha = senha;
this.primeiroNome = primeiroNome;
this.ultimoNome = ultimoNome;
this.tipoUsuarios = tipoUsuarios;
this.autorizacoes = autorizacoesUsuarios;
this.dadosUsuarios = dadosUsuarios;
this.config = config;
}
public Usuario(String login, String senha, String primeiroNome, String ultimoNome, String tipoUsuario, String[] campos) {
this.login = login;
this.senha = senha;
this.primeiroNome = primeiroNome;
this.ultimoNome = ultimoNome;
this.tipoUsuarios.add(new TipoUsuario(this, new Tipo(tipoUsuario)));
for(int i=0; i<campos.length; i++)
this.dadosUsuarios.add(new DadosUsuario(this, null, campos[i]));
}
#Id
#Column(name = "id", unique = true, nullable = false)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "login", nullable = false, length = 16)
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
#Column(name = "senha", nullable = false)
public String getSenha() {
return this.senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
#Column(name = "primeiro_nome", length = 32)
public String getPrimeiroNome() {
return this.primeiroNome;
}
public void setPrimeiroNome(String primeiroNome) {
this.primeiroNome = primeiroNome;
}
#Column(name = "ultimo_nome", length = 32)
public String getUltimoNome() {
return this.ultimoNome;
}
public void setUltimoNome(String ultimoNome) {
this.ultimoNome = ultimoNome;
}
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "tipo_usuario", joinColumns = { #JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { #JoinColumn(name = "fk_tipo") })
#LazyCollection(LazyCollectionOption.TRUE)
public List<TipoUsuario> getTipoUsuarios() {
return this.tipoUsuarios;
}
public void setTipoUsuarios(List<TipoUsuario> tipoUsuarios) {
this.tipoUsuarios = tipoUsuarios;
}
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "autorizacoes_usuario", joinColumns = { #JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { #JoinColumn(name = "fk_autorizacoes") })
#LazyCollection(LazyCollectionOption.TRUE)
public List<AutorizacoesUsuario> getAutorizacoes() {
return this.autorizacoes;
}
public void setAutorizacoes(List<AutorizacoesUsuario> autorizacoes) {
this.autorizacoes = autorizacoes;
}
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "dados_usuario", joinColumns = { #JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { #JoinColumn(name = "fk_dados") })
#LazyCollection(LazyCollectionOption.TRUE)
public List<DadosUsuario> getDadosUsuarios() {
return this.dadosUsuarios;
}
public void setDadosUsuarios(List<DadosUsuario> dadosUsuarios) {
this.dadosUsuarios = dadosUsuarios;
}
#OneToOne
#JoinColumn(name="fk_config")
public ConfigHorarioLivre getConfig() {
return config;
}
public void setConfig(ConfigHorarioLivre config) {
this.config = config;
}
}
AutorizacoesUsuario.java
#Entity
#Table(name = "autorizacoes_usuario", uniqueConstraints = #UniqueConstraint(columnNames = "id"))
public class AutorizacoesUsuario implements java.io.Serializable {
private int id;
private Usuario usuario;
private Autorizacoes autorizacoes;
public AutorizacoesUsuario() {
}
public AutorizacoesUsuario(Usuario usuario, Autorizacoes autorizacoes) {
this.usuario = usuario;
this.autorizacoes = autorizacoes;
}
#Id
#Column(name = "id", unique = true, nullable = false)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#OneToOne
#JoinColumn(name = "fk_usuario", nullable = false, insertable = false, updatable = false)
public Usuario getUsuario() {
return this.usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
#OneToOne
#JoinColumn(name = "fk_autorizacoes", nullable = false, insertable = false, updatable = false)
public Autorizacoes getAutorizacoes() {
return this.autorizacoes;
}
public void setAutorizacoes(Autorizacoes autorizacoes) {
this.autorizacoes = autorizacoes;
}
}
Autorizacoes.java
#Entity
#Table(name = "autorizacoes")
public class Autorizacoes implements java.io.Serializable {
private int id;
private String nome;
private String descricao;
public Autorizacoes() {
}
public Autorizacoes(String nome) {
this.nome = nome;
}
public Autorizacoes(String nome, String descricao) {
this.nome = nome;
this.descricao = descricao;
}
#Id
#Column(name = "id", unique = true, nullable = false)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "nome", nullable = false, length = 16)
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
#Column(name = "descricao", length = 140)
public String getDescricao() {
return this.descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
}
Full project available on github
--> https://github.com/klebermo/webapp_horario_livre
You need to either add fetch=FetchType.EAGER inside your ManyToMany annotations to automatically pull back child entities:
#ManyToMany(fetch = FetchType.EAGER)
A better option would be to implement a spring transactionManager by adding the following to your spring configuration file:
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
You can then add an #Transactional annotation to your authenticate method like so:
#Transactional
public Authentication authenticate(Authentication authentication)
This will then start a db transaction for the duration of the authenticate method allowing any lazy collection to be retrieved from the db as and when you try to use them.
The best way to handle the LazyInitializationException is to use the JOIN FETCH directive for all the entities that you need to fetch along.
Anyway, DO NOT use the following Anti-Patterns as suggested by some of the answers:
Open Session in View
hibernate.enable_lazy_load_no_trans
Sometimes, a DTO projection is a better choice than fetching entities, and this way, you won't get any LazyInitializationException.
Adding following property to your persistence.xml may solve your problem temporarily
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
As #vlad-mihalcea said it's an antipattern and does not solve lazy initialization issue completely, initialize your associations before closing transaction and use DTOs instead.
I too had this problem when I was doing unit Testing. A very Simple Solution to this problem is to use #Transactional annotation which keeps the session open till the end of the execution.
Your Custom AuthenticationProvider class should be annotated with the following:
#Transactional
This will make sure the presence of the hibernate session there as well.
The reason is that when you use lazy load, the session is closed.
There are two solutions.
Don't use lazy load.
Set lazy=false in XML or Set #OneToMany(fetch = FetchType.EAGER) In annotation.
Use lazy load.
Set lazy=true in XML or Set #OneToMany(fetch = FetchType.LAZY) In annotation.
and add OpenSessionInViewFilter filter in your web.xml
Detail See my post.
https://stackoverflow.com/a/27286187/1808417
For those who have this problem with collection of enums here is how to solve it:
#Enumerated(EnumType.STRING)
#Column(name = "OPTION")
#CollectionTable(name = "MY_ENTITY_MY_OPTION")
#ElementCollection(targetClass = MyOptionEnum.class, fetch = EAGER)
Collection<MyOptionEnum> options;
You can use hibernate lazy initializer.
Below is the code you can refer.
Here PPIDO is the data object which I want to retrieve
Hibernate.initialize(ppiDO);
if (ppiDO instanceof HibernateProxy) {
ppiDO = (PolicyProductInsuredDO) ((HibernateProxy) ppiDO).getHibernateLazyInitializer()
.getImplementation();
ppiDO.setParentGuidObj(policyDO.getBasePlan());
saveppiDO.add(ppiDO);
proxyFl = true;
}
A common practice is to put a #Transactional above your service class.
#Service
#Transactional
public class MyServiceImpl implements MyService{
...
}
First of all I'd like to say that all users who said about lazy and transactions were right. But in my case there was a slight difference in that I used result of #Transactional method in a test and that was outside real transaction so I got this lazy exception.
My service method:
#Transactional
User get(String uid) {};
My test code:
User user = userService.get("123");
user.getActors(); //org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role
My solution to this was wrapping that code in another transaction like this:
List<Actor> actors = new ArrayList<>();
transactionTemplate.execute((status)
-> actors.addAll(userService.get("123").getActors()));
There are cases where you don't need to put #Transactional annotation to your service method, like integration testing where you can just add #Transactional to your test method. You can get org.hibernate.LazyInitializationException when testing a method that just selects from database, which does not need to be transactional. For example, when you try to load an entity class which has a lazy fetch relation like below may cause this :
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Item> items;
so you add the #Transactional annotation to only to the test method.
#Test
#Transactional
public void verifySomethingTestSomething() {
I believe rather than enabling eager fetch, it make sense to re-initialise your entity where its needed to avoid LazyInitializationException exception
Hibernate.initialize(your entity);
For those using JaVers, given an audited entity class, you may want to ignore the properties causing the LazyInitializationException exception (e.g. by using the #DiffIgnore annotation).
This tells the framework to ignore those properties when calculating the object differences, so it won't try to read from the DB the related objects outside the transaction scope (thus causing the exception).
After changing the FetchType to EAGER, I still had the same problem. Turned out that I was using a user instance from session and the object was serialized in DB (I use Spring session JDBC), so no matter if I restarted spring boot the problem persisted. I should had requested it from the repository.
Add the annotation
#JsonManagedReference
For example:
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name = "autorizacoes_usuario", joinColumns = { #JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { #JoinColumn(name = "fk_autorizacoes") })
#JsonManagedReference
public List<AutorizacoesUsuario> getAutorizacoes() {
return this.autorizacoes;
}

Could not determine type for: java.util.List

I'm rather new to Hibernate and it turns out it's not a simple technology to learn... In the project I use hibernate version 4.2.0.CR1. I'm trying to create a base class for all database entities, as they all are supposed to contain some identifier and date of creation. What is weird is that at first, I crated class User and UserPicture without any base class and it worked perfectly fine and now that I added it, even though it's supposed to work just like before, it doesn't o_O and it keeps on throwing some weird exception about my list of pictures, that was not thrown before...
So I keep on getting following stacktrace:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: User, for columns: [org.hibernate.mapping.Column(profilePicture)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:314)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:292)
at org.hibernate.mapping.Property.isValid(Property.java:239)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:469)
at org.hibernate.mapping.UnionSubclass.validate(UnionSubclass.java:61)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1283)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1734)
at love.commons.database.DBManager.<init>(DBManager.java:28)
at love.commons.database.DBManagerTest.<clinit>(DBManagerTest.java:19)
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.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
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)
AbstractEntity:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable{
private static final long serialVersionUID = 1L;
protected Long id;
protected Date creationDate = new Date();
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.TABLE)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column
#NotNull
#Temporal(TemporalType.DATE)
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
User:
#Entity
#Table(name="User")
public class User extends AbstractEntity {
private static final long serialVersionUID = 1L;
#Column (unique=true, length=30)
#NotNull
private String login;
#Column (length=32)
#NotNull
private String password;
#NotNull
#Email
#Column (unique=true, length=80)
private String email;
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="owner")
private List<UserPicture> profilePictures = new LinkedList<UserPicture>();
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Transient
public void encryptPassword() {
this.password = md5(password);
}
public List<UserPicture> getProfilePicture() {
return Collections.unmodifiableList(profilePictures);
}
public void addProfilePicture(UserPicture profilePicture) {
profilePicture.setOwner(this);
profilePictures.add(profilePicture);
}
#Transient
private String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(input.getBytes(), 0, input.length());
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
}
UserPicture:
#Entity
public class UserPicture extends AbstractEntity {
private static final long serialVersionUID = 1L;
#Column(length=734004)
private byte [] picture = null;
#ManyToOne(fetch=FetchType.LAZY)
#Column(name="owner")
#JoinColumn(nullable=false,name="id")
private User owner;
public UserPicture() {
picture = null;
}
public UserPicture(InputStream stream) {
try {
this.picture = new byte[stream.available()];
stream.read(picture);
} catch (IOException e) {
e.printStackTrace();
}
}
public UserPicture(byte [] picture) {
this.picture = picture;
}
public byte[] getPicture() {
return picture;
}
public void setPicture(byte[] picture) {
this.picture = picture;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
So what am I doing wrong? Why do I keep on getting the exception?
AbstractEntity must not be annotated with #Entity and #Inheritance. It must be annotated with #MappedSuperclass. Indeed, this inheritance is only used to inherit common attributes, and that's what MappedSuperclass is for.
The exception you get is caused by the lack of coherence in the position of your mapping annotations. The base superclass annotated the getters, and the subclasses annotate the fields. Hibernate uses the position of the Id annotation to determine the access type of the entity. Since #Id is on a getter, it only considers the annotations placed on getters, and ignores those placed on fields. Put all your annotations either on fields (which I would recommend) or on getters.
Moreover, your getter is badly named. It should be getProfilePictures() and not getProfilePicture().
From Hibernate 5.2 documentation:
By default, the placement of the #Id annotation gives the default
access strategy.
For your case, hibernate will use AccessType.PROPERTY both for UserPicture and User entities hence the exception, to use field mapping strategy, you should define #Access strategy explicitly :
#Entity
#Table(name="User")
#Access( AccessType.FIELD )
public class User extends AbstractEntity {
...
}
#Entity
#Access( AccessType.FIELD )
public class UserPicture extends AbstractEntity {
....
}
I had the same problem, i figured out that hibernate tried to use Parent using properties accessorso i solved the problem by using #Access annotation to force use fields
#Entity
#Table(name = "MyTable")
#Access(AccessType.FIELD)
public class MyEntity{
......
}
you can try to add #ElementCollection mapping above the List declaration.

Categories

Resources