Hibernate:DB中没有更新内部类值

时间:2015-12-17 21:07:48

标签: java mysql hibernate spring-mvc jpa

我有一个应用程序(使用注释的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)

1 个答案:

答案 0 :(得分:1)

此外,如上所述,对于标记为瞬态的字段,JPA规范要注意一些要点:

  1. 实体类必须是顶级类
  2. 实体类必须具有无参数构造函数。实体类也可以有其他构造函数。 no-arg构造函数必须是公共的或受保护的。
  3. 我怀疑你真正想要使用的是可嵌入

      

    在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;
        }
    }