Подтвердить что ты не робот

Дублировать столбцы при использовании EmbeddedId с отображением ManyToOne с Ebean

У меня есть модель под названием "EventCheckin", которая имеет сопоставление ManyToOne с "Событием" и "Пользователь". PrimaryKey таблицы EventCheckin - это идентификатор пользователя и идентификатор события. Я пытаюсь представить это с помощью "EmbeddedId" в моей модели EventCheckin, но когда я пытаюсь сохранить EventCheckin, он пытается дважды вставлять значения user_id и event_id в таблицу, что явно не выполняется:

Caused by: org.h2.jdbc.JdbcSQLException: Duplicate column name "USER_ID"; SQL statement:
insert into eventCheckin (event_id, user_id, latitude, longitude, user_id, event
_id) values (?,?,?,?,?,?) [42121-158]

Класс EventCheckin:

@Entity
@Table(name="eventCheckin")
public class EventCheckin extends Model
{
    @EmbeddedId public CheckinId id;

    @MapsId("userId")
    @JoinColumn(name="user_id")
    @ManyToOne public User user;

    @MapsId("eventId")
    @JoinColumn(name="event_id")
    @ManyToOne public Event event;

    .....
}

CheckinId EmbeddedId class::

@Embeddable 
public class CheckinId implements Serializable
{
    public Long eventId;  
    public String userId;
    .....
}

И моя таблица базы данных для EventCheckin определяется следующим образом:

create table eventCheckin (
    user_id                   varchar(255) not null,
    event_id                  bigint not null,
    latitude                  float,
    longitude                 float,
    constraint pk_eventCheckIn primary key (user_id,event_id),
    foreign key (user_id) references user (email),
    foreign key (event_id) references event (id)
);
4b9b3361

Ответ 1

Похоже, вы пытаетесь сделать то же самое через @MapsId и @EmbeddedId. Один (рабочий) вариант заключается в том, чтобы перейти на IdClass (equals, hashcode, дополнительные атрибуты и т.д.):

    @Entity
    public class User {
        @Id public String id;
    }

    @Entity
    public class Event {
        @Id public long id;
    }

    public class CheckinId implements Serializable {
        public Long event;
        public String user;
    }

    @Entity
    @IdClass(CheckinId.class)
    @Table(name="eventCheckin")
    public class EventCheckin {

        @Id
        @JoinColumn(name="user_id")
        @ManyToOne public User user;

        @Id
        @JoinColumn(name="event_id")
        @ManyToOne public Event event;
    }

Ответ 2

Эта ошибка возникает из-за того, что столбцы user_id и event_id используются составным ключом и в то же время используются @ManyToOne сопоставлениями. Решение состоит в том, чтобы добавить атрибуты insertable = false, updatable = false в @Joincolumn annotaion. Вот рабочий код для этого решения:

EventChekin.java:

@Entity
@Table(name="eventCheckin")
public class EventCheckin extends Model {

    public EventCheckin() {
        id = new CheckinId();
    }

    @EmbeddedId 
    public CheckinId id;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name="user_id", insertable = false, updatable = false)
    private User user;

    @ManyToOne
    @MapsId("eventId")
    @JoinColumn(name="event_id", insertable = false, updatable = false)
    private Event event;

    public void setUser(User aUser) {
        user = aUser;
        id.userId = aUser.getId();
    }

    public void setEvent(Event aEvent) {
        event = aEvent;
        id.eventId = aEvent.getId();
    }
}

Checkin.java

@Embeddable 
public class CheckinId implements Serializable {

    public Long eventId;
    public String userId;

    @Override
    public int hashCode() {
        return eventId.intValue() + userId.length();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) 
            return true;
        CheckinId c = (CheckinId)obj;
        if(c==null)
        return false;
        if (c.eventId.equals(eventId) && c.userId.equals(userId)) {
            return true;
        }
        return false;
    }
}