我有一个应用程序(使用注释的Spring 4 MVC + Hibernate 4 + MySQL + Maven集成示例),使用基于注释的配置将Spring与Hibernate集成。我想保留内部类而不是添加字段作为属性DeviceEvent对象
数据库上的这个表:
CREATE TABLE `t_device_event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`device_event_lat` float(10,6) DEFAULT NULL,
`device_event_lng` float(10,6) DEFAULT NULL,
`device_id` int(11) unsigned NOT NULL,
`device_event_message` varchar(100) DEFAULT NULL,
`device_event_received` TIMESTAMP ,
`coordinates` point NULL,
PRIMARY KEY (`id`),
KEY `device_id` (`device_id`),
CONSTRAINT `t_device_event_ibfk_1` FOREIGN KEY (`device_id`) REFERENCES `t_device` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
此域对象:
@Entity
@Table(name="t_device_event")
public class DeviceEvent {
public DeviceEvent() {
super();
}
public class Coordinates {
public Coordinates() {
super();
}
@Column(name = "device_event_lat")
private Double lat;
@Column(name = "device_event_lng")
private Double lng;
public Coordinates(Double lat, Double lng) {
super();
this.lat = lat;
this.lng = lng;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
public Double getLng() {
return lng;
}
public void setLng(Double lng) {
this.lng = lng;
}
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne
@JoinColumn(name="device_id")
private Device device;
@Column(name = "device_event_received")
private Long received;
@Column(name = "device_event_message")
private String message;
@Embedded
private Coordinates coordinates;
public Coordinates getCoordinates() {
return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public Long getReceived() {
return received;
}
public void setReceived(Long received) {
this.received = received;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public DeviceEvent(Device device) {
super();
this.device = device;
}
}
和控制器中的这段代码:
Device device = deviceService.findByKey("de305d54-75b4-431b-adb2-eb6b9e546014");
DeviceEvent deviceEvent = new DeviceEvent(device);
deviceEvent.setCoordinates(deviceEvent.new Coordinates((double) 44.4, (double) 33.3));
deviceEvent.setMessage("message");
deviceEventService.save(deviceEvent);
但我有这个错误:
org.hibernate.InstantiationException: No default constructor for entity: : fr.telecom.model.DeviceEvent$Coordinates
org.hibernate.tuple.PojoInstantiator.instantiate(PojoInstantiator.java:120)
org.hibernate.tuple.component.AbstractComponentTuplizer.instantiate(AbstractComponentTuplizer.java:101)
org.hibernate.type.ComponentType.instantiate(ComponentType.java:561)
org.hibernate.type.ComponentType.deepCopy(ComponentType.java:482)
org.hibernate.type.TypeHelper.deepCopy(TypeHelper.java:67)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:280)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
com.ideefe.iot.dao.AbstractDao.persist(AbstractDao.java:34)
com.ideefe.iot.dao.DeviceEventDaoImpl.save(DeviceEventDaoImpl.java:31)
com.ideefe.iot.service.DeviceEventServiceImpl.save(DeviceEventServiceImpl.java:19)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy73.save(Unknown Source)
fr.telecom.controller.AppController.listDevices(AppController.java:61)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
答案 0 :(得分:1)
此外,如上所述,对于标记为瞬态的字段,JPA规范要注意一些要点:
我怀疑你真正想要使用的是可嵌入:
在JPA中嵌入目标对象数据的关系 源对象表被认为是嵌入式关系,并且 目标对象被视为可嵌入对象。
https://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Embeddables
这将如下所示。
@Embeddable
public class Coordinates {
@Column(name = "device_event_lat")
private Double lat;
@Column(name = "device_event_lng")
private Double lng;
protected Coordinates(){
//JPA requires no-arg constructor
}
public Coordinates(Double lat, Double lng) {
super();
this.lat = lat;
this.lng = lng;
}
}
@Entity
@Table(name="t_device_event")
public class DeviceEvent {
//other fields ommitted
@Embedded
private Coordinates coordinates;
public Coordinates getCoordinates() {
return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
}
}