springdata jpa中具有外键的OneToMany关系,外键也是Composite主键的一部分

时间:2020-07-16 04:08:19

标签: java hibernate spring-mvc spring-data-jpa

我是Spring Hibernate框架的新手,并且正在研究车辆跟踪应用程序,该类有两个类别的Vehicle和Vehicle阅读类。车辆方面存在一对多关系,车辆阅读类中存在多对一关系。

车辆类的主键是“ vin”列,而这是vehicleReadings类中的外键。

vehicleReadings类的主键是ReadingId,它是带有vehicle_id和时间戳的复合键。

车辆类别的代码为:

@Entity
@Table(name = "Vehicles")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Vehicle {

    @Id
    @Column(name = "vin")
    private String vin;

    @Column(name = "make")
    private String make;
    @Column(name = "model")
    private String model;
    @Column(name = "year")
    private Integer year;

    @Column(name = "redlineRpm")
    private Integer redlineRpm;
    @Column(name = "maxFuelVolume")
    private Integer maxFuelVolume;
    @Column(name = "lastServiceDate")
    private String lastServiceDate;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "vehicle")
    Set<VehicleReadings> vehicleReadings;
}

“车辆读数”类的代码:

@Entity
@Table(name = "Readings")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class VehicleReadings {
        @EmbeddedId
        private ReadingId readingId;

        @ManyToOne(fetch = FetchType.EAGER,optional = false)
        @JoinColumn(name ="vin", referencedColumnName = "vin")
        @MapsId("vehicleId")
        private Vehicle vehicle;

        @Column(name= "latitude")
        private Float latitude;

        @Column(name = "longitude")
        private Float longitude;

        @Column(name = "fuelvolume")
        private Float fuelVolume;

        @Column(name = "checkenginelighton")
        private Boolean checkEngineLightOn;

        @Column(name = "enginecoolantlow")
        private Boolean engineCoolantLow;

        @Column(name = "enginerpm")
        private Integer engineRpm;


}

readsId类的代码

@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class ReadingId implements Serializable {

    @Column(name = "vin")
    String vehicleId;

    @Column(name = "timestamp")
    String timestamp;
}

收到针对读数表的REST请求时,会发生以下错误:

org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [io.egen.car_tracker_application.domain.VehicleReadings.vehicle]
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:87) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:509) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:97) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:115) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:718) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:704) ~[hibernate-core-5.4.17.Final.jar:5.4.17.Final]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_251]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_251]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_251]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_251]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at com.sun.proxy.$Proxy105.persist(Unknown Source) ~[na:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_251]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_251]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_251]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_251]
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314) ~[spring-orm-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at com.sun.proxy.$Proxy105.persist(Unknown Source) ~[na:na]
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:554) ~[spring-data-jpa-2.3.1.RELEASE.jar:2.3.1.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_251]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_251]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_251]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_251]
    at org.springframework.data.repository.core.support.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72) ~[spring-data-commons-2.3.1.RELEASE.jar:2.3.1.RELEASE

有人可以指导我如何正确设置实体之间的关系吗?

编辑:

通过REST输入输入的样本读数表:

{
   "vin": "1HGCR2F3XFA027534",
   "latitude": 41.803194,
   "longitude": -88.144406,
   "timestamp": "2017-05-25T17:31:25.268Z",
   "fuelVolume": 1.5,
   "speed": 85,
   "engineHp": 240,
   "checkEngineLightOn": false,
   "engineCoolantLow": true,
   "cruiseControlOn": true,
   "engineRpm": 6300
}

0 个答案:

没有答案
相关问题