我有两个下面的SQL表:

CREATE TABLE lost_travelers
(
    id BIGINT PRIMARY KEY DEFAULT nextval('global_seq'),
    /* a lot of other columns */
);

CREATE TABLE lost_travelers_locations
(
    lost_traveler_id BIGINT NOT NULL,
    latitude REAL NOT NULL,
    longitude REAL NOT NULL,
    location_type VARCHAR NOT NULL,

    FOREIGN KEY (lost_traveler_id) REFERENCES travelers (id) ON DELETE CASCADE
);


我希望它位于单独的表中的原因是,lost_travelers表实际上具有很多属性。

我遇到的问题与JPA /休眠映射有关。基本上,我不希望lost_travelers_locations成为实体(具有ID)。但是,当我尝试使用@Embeddable注解时,出现以下错误。

Caused by: org.hibernate.AnnotationException: model.location.LostTravelerLocation must not have @Id properties when used as an @EmbeddedId: model.traveler.LostTraveler.lostTravelerLocation


我的课程分别是:

LostTraveler位置:

@Embeddable
@Table(name = "lost_travelers_locations")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class LostTravelerLocation extends Location
{
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "lost_traveler_id")
    private LostTraveler lostTraveler;

    @Enumerated(EnumType.STRING)
    @Column(name = "location_type")
    private LocationType locationType;

    public LostTraveler getLostTraveler()
    {
        return lostTraveler;
    }

    public void setLostTraveler(LostTraveler lostTraveler)
    {
        this.lostTraveler = lostTraveler;
    }

    public LocationType getLocationType()
    {
        return locationType;
    }

    public void setLocationType(LocationType locationType)
    {
        this.locationType = locationType;
    }
}


位置类别:

@MappedSuperclass
public abstract class Location
{
    @Column(name = "latitude")
    @NotNull
    private float longitude;

    @Column(name = "longitude")
    @NotNull
    private float latitude;

    public float getLongitude()
    {
        return longitude;
    }

    public void setLongitude(float longitude)
    {
        this.longitude = longitude;
    }

    public float getLatitude()
    {
        return latitude;
    }

    public void setLatitude(float latitude)
    {
        this.latitude = latitude;
    }
}


失落的旅行者:

@Entity
@Table(name = "lost_travelers")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class LostTraveler extends Traveler
{
    @EmbeddedId
    private LostTravelerLocation lostTravelerLocation;

    /* A lot of other properties */

   public LostTravelerLocation getLostTravelerLocation()
   {
        return lostTravelerLocation;
   }

   public void setLostTravelerLocation(LostTravelerLocation lostTravelerLocation)
   {
        this.lostTravelerLocation = lostTravelerLocation;
   }

}


抽象类旅行者:

@MappedSuperclass
public abstract class Traveler extends EntityWithId
{
    /* A lot of properties as well */
}


EntityWithId:

@MappedSuperclass
public class EntityWithId
{
    @Id
    @SequenceGenerator(name = "global_seq", sequenceName = "global_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "global_seq")
    private Long id;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }
}


我现在不是问题所在。我只是坚持要求LostTraveler是实体,而LostTravelerLocation不是。提前致谢。

最佳答案

在实体上使用@Embeddable时,不能声明@Table注释,因为它会引起冲突。一方面,您说这可以嵌入到任何表中,另一方面,您说它具有独立的表,JPA会抱怨。我要注意的另一件事是,您未嵌入可嵌入对象(我看不到@Embedded所在的位置),而是使用了主要用于复合键ID的@EmbeddedId

@Embeddable / @Embedded可能不是您要执行的操作的合适方法,特别是因为您要创建两个具有一对一映射的表。使用一对一映射或将LostTravelerLocation正确嵌入到LostTraveler

10-06 00:57