我正在尝试编写一个相对通用的REST实现来支持我所有数据库实体的通用CRUD。使用带有休眠和杰克逊的弹簧。
但是,由于某种原因,GET(特定项目标识)操作失败,并列出了错误。
BrakeType.java(型号):
@Entity
@Table(name = "BrakeType")
public class BrakeType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "Id", nullable = false, unique = true)
private Integer id;
@Column(name = "brakeCode", nullable = false)
private String brakeCode;
@Column(name = "brakeDescription", nullable = false)
private String brakeDescription;
...getters, setters, toString()
}
AbstractDao.java
public abstract class AbstractDao {
@Autowired
private SessionFactory sessionFactory;
protected Session getSession() { return sessionFactory.getCurrentSession(); }
public void persist(Object entity) { getSession().persist(entity); }
public void delete(Object entity) { getSession().delete(entity); }
}
GenericDao.java
public interface GenericDao<T> {
T save(T obj);
List<T> findAll();
void deleteById(Integer id);
T findById(Integer id);
T update(T obj);
}
GenericDaoOps.java
public abstract class GenericDaoOps<T> extends AbstractDao implements GenericDao<T> {
public abstract Class<T> getPClass();
public String getTableName() { return getPClass().getSimpleName(); }
@Override
public T save(T obj) { persist(obj); return obj; }
@Override
public List<T> findAll() {
Criteria criteria = getSession().createCriteria(getPClass(), getPClass().getSimpleName());
return (List<T>) criteria.list();
}
@Override
public void deleteById(Integer id) { getSession().delete(findById(id)); }
@Override
public T findById(Integer id) { return getSession().load(getPClass(), id); }
@Override
public T update(T obj) { getSession().update(obj); return obj; }
}
BrakeTypeDao.java:
public interface BrakeTypeDao extends GenericDao<BrakeType> { }
BrakeTypeDaoImpl.java
public class BrakeTypeDaoImpl extends GenericDaoOps<BrakeType> implements BrakeTypeDao {
@Override
public Class<BrakeType> getPClass() {
return BrakeType.class;
}
}
BrakeTypeController.java:
@RestController
@RequestMapping(value = "/", produces = {APPLICATION_JSON_VALUE})
@Api(value = "/lists", description = "REST Api SIMA application - administration")
@Transactional
public class SimaBrakeTypeController {
private static final String obj_name = "brake type";
private static final String obj_name_api = "/lists/brake_type";
private static final String obj_names = "brake types";
private static final String obj_names_api = "/lists/brake_types";
private final Logger logger = Logger.getLogger(HelloController.class);
@Autowired
private Interfaces.BrakeTypeDao dao;
@ApiOperation(value = "List of all " + obj_names, notes = "List of all " + obj_names + " for SIMA system.", response = BrakeType[].class)
@ApiResponses(value = { @ApiResponse(code = HttpServletResponse.SC_OK, message = "OK") })
@RequestMapping(value = obj_names_api, method = RequestMethod.GET)
public ResponseEntity<SmartHttpResult> simaBrakeTypeGetAll() {
final List<BrakeType> usrList = dao.findAll();
logger.debug("GET ALL " + obj_names.toUpperCase() + ":");
return Response.getHttpResult(usrList, usrList.size() > 0, "/", obj_names.toUpperCase().replace(" ", "_") + "_NOT_FOUND");
}
@ApiOperation(value = obj_name, notes = obj_name + " for current ID.", response = BrakeType.class)
@ApiResponses(value = { @ApiResponse(code = HttpServletResponse.SC_OK, message = "OK") })
@RequestMapping(value = obj_name_api + "/{id}/", method = RequestMethod.GET)
public ResponseEntity<SmartHttpResult> simaBrakeTypeGet(@PathVariable("id") final Integer id) {
BrakeType obj = dao.findById(id);
logger.debug(String.format("GET %S: %d", obj_name, id));
return Response.getHttpResult(obj, obj != null, "/", String.format("%S_NOT_FOUND", obj_name.replace(" ", "_")));
}
@ApiOperation(value = "Adding " + obj_name, notes = "Add new " + obj_name + ". Returns id of new " + obj_name + ".", response = BrakeType.class)
@ApiResponses(value = { @ApiResponse(code = HttpServletResponse.SC_CREATED, message = "Created") })
@ResponseStatus(HttpStatus.CREATED)
@RequestMapping(value = obj_name_api, method = RequestMethod.POST)
public ResponseEntity<SmartHttpResult> simaBrakeTypeAdd(@RequestBody final BrakeType obj) {
BrakeType inserted = dao.save(obj);
// for Mockito (unit test) simulate insert ona database
if (dao.getClass().getName().contains("Mockito") && obj.getId() != null)
inserted = obj;
logger.debug(String.format("INSERT %S: %s", obj_name, inserted.toString()));
return Response.getHttpResult(inserted, inserted != null, obj_name.toUpperCase() + "_CREATED", obj_name.toUpperCase() + "USER_NOT_CREATED");
}
@ApiOperation(value = "Update " + obj_name, notes = "Update/edit " + obj_name + ".Returns complete user object.",
response = BrakeType.class)
@ApiResponses(value = { @ApiResponse(code = HttpServletResponse.SC_OK, message = "OK") })
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = obj_name_api, method = RequestMethod.PUT)
public ResponseEntity<SmartHttpResult> simaBrakeTypeEdit(@RequestBody final BrakeType obj) {
BrakeType inserted = dao.update(obj);
logger.debug(String.format("UPDATE %S: %s", obj_name, inserted.toString()));
return Response.getHttpResult(inserted, inserted != null, obj_name.toUpperCase() + "_UPDATED",
obj_name.toUpperCase() + "_NOT_UPDATED");
}
@ApiOperation(value = "Delete " + obj_name,
notes = "Delete current " + obj_name + ". Returns deleted " + obj_name + " ID.",
response = BrakeType.class)
@ApiResponses(value = {@ApiResponse(code = HttpServletResponse.SC_OK, message = "OK") })
@RequestMapping(value = obj_name_api + "/{id}/", method = RequestMethod.DELETE)
public ResponseEntity<SmartHttpResult> simaBrakeTypeDelete(@PathVariable("id") final Integer id) {
dao.deleteById(id);
logger.debug(String.format("DELETE %S: %d", obj_name, id));
return Response.getHttpResult(id, id != null, obj_name.toUpperCase() + "_DELETED", obj_name.toUpperCase() + "_NOT_DELETED");
}
}
除GET / lists / break_type / {id} /
外,所有操作都有效抛出异常:
HTTP Status 500 - Could not write content: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"])
type Exception report
message Could not write content: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"])
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"])
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:271)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:167)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:185)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:127)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: sima.model.SmartHttpResult["result"]->sima.model.BrakeType_$$_jvstdfd_3["id"])
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:199)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:683)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:693)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1387)
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:889)
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:264)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:167)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:185)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:127)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:148)
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)
sima.model.BrakeType_$$_jvstdfd_3.getId(BrakeType_$$_jvstdfd_3.java)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:497)
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:654)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:693)
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675)
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1387)
com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:889)
org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:264)
org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:167)
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:185)
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:80)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:127)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
我错过了什么?
编辑:我刚刚发现,如果我更改GenericDaoOps.java,则运行findById:
@Override
public T findById(Integer id) {
//return getSession().load(getPClass(), id);
Criteria criteria = getSession().createCriteria(getPClass());
criteria.add(Restrictions.eq("id", id));
return (T) criteria.uniqueResult();
}
事情开始起作用......
有什么区别???