简体   繁体   中英

@EmbeddedId alongside with @Id exception

I have two SQL table which are below:

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

The reason I want it to be in separate tables is because the lost_travelers table has really a lot of properties.

The problem I've encountered has to do with JPA/Hibernate mapping. Basically, I don't want lost_travelers_locations to be an Entity (have id). However, when I try to use @Embeddable annotation I get the following error.

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

Respectively, my classes are:

LostTravelerLocation:

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

Location class:

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

LostTraveler:

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

}

Abstract class Traveler:

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

I don't now what the problem is. I simply insist on LostTraveler being an Entity , while LostTravelerLocation not. Thanks in advance.

When using using @Embeddable on an entity, you cannot declare the @Table annotation because it causes conflict. On the one end you are saying this will embeddable on any table, on the other hand you are saying it had a standalone table, JPA will complain. Another thing I'm noting is that you are not embedding the embeddable (I don't see where @Embedded ), instead, you are using @EmbeddedId which is is primarily used for Composite-Key Id's.

Perhaps @Embeddable / @Embedded is not a suitable approach for what you want to do, especially since you want to create two tables that have a one-to-one mapping. Either use one-to-one mapping or embed the LostTravelerLocation into the LostTraveler correctly

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM