【问题标题】:Hibernate: inner class values not updaded in the DBHibernate:内部类值未在数据库中更新
【发布时间】:2015-12-17 21:07:48
【问题描述】:

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

【问题讨论】:

  • 你的意思是被标记为瞬态的字段?!

标签: java mysql hibernate spring-mvc jpa


【解决方案1】:

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

  1. 实体类必须是顶级类
  2. 实体类必须有一个无参数的构造函数。实体类也可能有其他构造函数。无参数构造函数必须是公共的或受保护的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多