Estoy intentando crear dos entidades donde ambas entidades tienen embeddedIds. Una de las entidades tiene 2 referencias a la otra entidad, donde ambas referencias están relacionadas como ManyToOne.Java EE 6 JPA 2 La relación ManyToOne crea clave externa no válida
Los códigos de ejemplo se escriben a continuación;
@Embeddable
public class ItemPK {
@Column(nullable = false, length = 100)
private String itemId;
@Column(name = "item_client_id", nullable = false)
private int clientId;
...
}
@Entity
@Table(name = "item")
public class Item {
@EmbeddedId
private ItemPK id;
@ManyToOne
@JoinColumn(name = "item_client_id")
private Client client;
@OneToMany(mappedBy="item", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<RelatedItem> relatedItems;
@OneToMany(mappedBy="relatedItem", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<RelatedItem> relatedItemsRHS;
...
}
@Embeddable
public class RelatedItemPK {
@Column(name = "itemId", length = 100, nullable = false)
private String itemId;
@Column(name = "item_client_id", nullable = false)
private int clientId;
@Column(name = "relatedItemId", length = 100, nullable = false)
private String relatedItemId;
@Column(name = "related_item_client_id", nullable = false)
private int relatedItemClientId;
...
}
@Entity
@Table(name = "related_item")
public class RelatedItem {
@EmbeddedId
private RelatedItemPK id;
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@JoinColumns({
@JoinColumn(name="itemId", referencedColumnName="itemId", insertable=false, updatable=false),
@JoinColumn(name="item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false)
})
private Item item;
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@JoinColumns({
@JoinColumn(name="related_item_client_id", referencedColumnName="item_client_id", insertable=false, updatable=false),
@JoinColumn(name="relatedItemId", referencedColumnName="itemId", insertable=false, updatable=false)
})
private Item relatedItem;
...
}
El problema es que al crear claves foráneas para la entidad RelatedItem, obtuve una SQLException. Es la segunda relación ManyToOne que falla. La generación de SQL clave externa está por debajo,
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId)
Desde tabla de elementos es indexado por primera vez por itemId luego por item_client_id, esta declaración hace que MySQL para producir un error.
me gustaría cambiar la ubicación de las columnas para que el SQL debe ser similar a la siguiente,
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_relatedItemId FOREIGN KEY (relatedItemId, related_item_client_id) REFERENCES item (itemId,item_client_id)
He intentado cambiar el orden de "s" JoinColumn pero el resultado no cambió. También intenté cambiar el nombre de los campos para comprobar si el proveedor de persistencia elige el orden por nombre de columna, pero de nuevo el resultado no cambió.
Entonces, ¿hay alguna manera de aplicar el orden de las columnas?
p.s. Yo uso siguientes cosas:
- MySQL 5.1
- EclipseLink 2.0.0
- Java EE 6
- JPA 2
- GlassFish v3
Editar: EclipseLink produce después de SQL, que no se ejecuta;
CREATE TABLE related_item (SIMILARITY DOUBLE, widget_id INTEGER NOT NULL, relatedItemId VARCHAR(100) NOT NULL, itemId VARCHAR(100) NOT NULL, related_item_client_id INTEGER NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (widget_id, relatedItemId, itemId, related_item_client_id, item_client_id));
CREATE TABLE item (IMAGEURL VARCHAR(2048), STATUS VARCHAR(64), URL VARCHAR(2048), PRICE DOUBLE, STOCK INTEGER, DESCRIPTION TEXT(64000), NAME VARCHAR(255), ITEMID VARCHAR(100) NOT NULL, item_client_id INTEGER NOT NULL, PRIMARY KEY (ITEMID, item_client_id));
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_itemId FOREIGN KEY (itemId, item_client_id) REFERENCES item (itemId, item_client_id);
ALTER TABLE related_item ADD CONSTRAINT FK_related_item_related_item_client_id FOREIGN KEY (related_item_client_id, relatedItemId) REFERENCES item (item_client_id, itemId);
ALTER TABLE item ADD CONSTRAINT FK_item_item_client_id FOREIGN KEY (item_client_id) REFERENCES client (ID);
¿Cuál es el error? El orden del campo en la restricción no debería tener ningún efecto.(también incluye el SQL generado para producir el error. – James
El orden de las restricciones es importante en MySQL. Debe haber un índice correspondiente en la tabla de destino donde la primera clave del índice es igual a la primera columna en la lista de restricciones. – bdaylik