jpa - Duplicar columnas al usar EmbeddedId con un mapeo ManyToOne con Ebean
playframework playframework-2.0 (2)
Parece que intentas hacer lo mismo a través de @MapsId y @EmbeddedId. Una opción (de trabajo) es ir para IdClass (es igual a, código de hash, atributos adicionales, etc.):
@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;
}
Tengo un modelo llamado "EventCheckin" que tiene una asignación ManyToOne a un "Evento" y un "Usuario". La clave principal de la tabla "EventCheckin" es la identificación del usuario y la identificación del evento. Intento representar esto usando un "EmbeddedId" en mi modelo EventCheckin, pero cuando intento guardar un EventCheckin, intenta poner dos veces los valores user_id y event_id en la tabla, lo que obviamente falla:
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]
Clase 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 clase EmbeddedId ::
@Embeddable
public class CheckinId implements Serializable
{
public Long eventId;
public String userId;
.....
}
Y mi tabla de base de datos para EventCheckin se define así:
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)
);
Este error se produce porque las columnas user_id
y event_id
son utilizadas por la clave compuesta y al mismo tiempo son utilizadas por @ManyToOne
mappings. La solución es agregar insertable = false, updatable = false
attributes a @Joincolumn
annotaion. Aquí está el código de trabajo para esta solución:
EventChekin.java:
@Entity
@Table(name="eventCheckin")
public class EventCheckin extends Model
{
public EventCheckin() {
id = new CheckinId();
}
@EmbeddedId public CheckinId id;
@MapsId("userId")
@JoinColumn(name="user_id", insertable = false, updatable = false)
@ManyToOne private User user;
@MapsId("eventId")
@JoinColumn(name="event_id", insertable = false, updatable = false)
@ManyToOne 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;
}
}