java - Hibernate:内部类值未在数据库中更新

标签 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;
    }
}

Controller 中的这段代码:

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)

最佳答案

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

  1. 实体类必须是顶级类
  2. 实体类必须具有无参数构造函数。实体类还可以有其他构造函数。无参数构造函数必须是公共(public)的或 protected 。

我怀疑您真正想要使用的是使用Embeddable:

In JPA a relationship where the target object's data is embedded in the source object's table is considered an embedded relationship, and the target object is considered an Embeddable object.

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

关于java - Hibernate:内部类值未在数据库中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34344254/

相关文章:

javascript - 为什么我无法读取在 POST 中收到的参数?

Java 语义 - 有没有办法写得更好?

php - 如何从 Laravel 中的 HTML 表中获取值

MySQL INSERT IF(自定义 if 语句)

mysql - 使用phpmyadmin导入巨大的sql文件

java - Vaadin 和 Hibernate - 正确关闭与数据库的连接

spring - grails.gorm.transactions.Transactional不回滚

java - 限制每个 JTextArea 行上的字符数

java - 使用 Univocity 将注释 bean 转为部分记录

java - Hibernate通过rest api进行插入操作