I have a master table with a prodKey string as ID. I have a sub table which has 2 key fields, prodKey and lineNo. I created a Composite Key of these 2 fields (embedded entity) and then created the sub table with this Composite Key. However, I cannot set a Composition field on the Master table to this sub-table records. It does not show as an option. How I do I link these 2 tables ?
Do I need to use UUIDs in every table which I need to link up ?
Hi,
If I have correctly understood, you want to link the entities thought the prodKey property which is a part of Composite PK. It is possible but coding is required (is not supported out of the box). How to create such associations was described several times on this forum. For instance in this topic.
I have tried the example. After I have made the changes, I can see the sub table as an option to create a Composition in the master table. But when I do this and run the project, the system failed to start and complained about an Eclipse Persistence Exception.
Hi,
I have prepared a little sample project to show how the entities might be linked through fields that are parts of Composite PK.
Note that this way is a bit hacky and is not supported by Studio.
In my sample:
OrderLine entity has two links: to Order and Product. They are presented by datatypes and assembled to Composite PK:
@MetaClass(name = "sample_KeyEntity")
@Embeddable
public class KeyEntity extends EmbeddableEntity {
private static final long serialVersionUID = -3160428472596560086L;
@Column(name = "ORDER_LINK")
private UUID orderLink;
@Column(name = "PRODUCT_CODE", length = 10)
private String productCode;
And @Transient@MetaProperty present the associations in OrderLine.
@Table(name = "SAMPLE_ORDER_LINE")
@Entity(name = "sample_OrderLine")
@NamePattern("%s %s|order,product")
public class OrderLine extends BaseGenericIdEntity<KeyEntity> {
private static final long serialVersionUID = -3872032066065715379L;
@EmbeddedId
private KeyEntity id;
@MetaProperty
@Transient
private Order order;
@Transient
@MetaProperty
private Product product;
@Column(name = "QUANTITY")
private Integer quantity;
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Product getProduct() {
if (this.product == null && id.getProductCode() != null) {
DataManager dm = AppBeans.get(DataManager.class);
product = dm.load(LoadContext.create(Product.class).setId(id.getProductCode()));
}
return product;
}
public void setProduct(Product product) {
this.product = product;
if (product != null) {id.setProductCode(product.getId());}
}
public Order getOrder() {
if (this.order == null && id.getOrderLink() != null) {
DataManager dm = AppBeans.get(DataManager.class);
order = dm.load(LoadContext.create(Order.class).setId(id.getOrderLink()));
}
return order;
}
public void setOrder(Order order) {
this.order = order;
if (order != null) {id.setOrderLink(order.getId());}
}
...
In Order: one_to_many Collection with the @JoinColumn annotation instead of “mappedBy”.
As there was no “mappedBy” defined, we should manually fill the link to Order, when creating a new OrderLine.
This could be done in the controller of the OrderEdit screen
Unfortunately, this MapsId JPA tag does not work for Cuba if the parent has > 1 field (composite key) as PK. I tried to create an Association (single attribute) or use Embedded in the PK class of the child, but Cuba does not allow it.
MapsId only works if the PARENT (i.e. Order) only has 1 key field (e.g. Order ID).
If the parent has 2 key fields or more (composite key), I am not sure how use it then.
What I need is a 3 level relationship: Parent -> Child -> Grandchild (has 3 key fields, 2 coming from Child).
e.g if each of the Orderline has a list of Remarks associated with it, how do can I define it ?
Note: I haven’t used this kind of composition with cuba, so I don’t have any experience on what kind of problems you might encounter using this kind of model. Doesn’t seem to be well supported at the moment. It should work with JPA/EclipseLink, so I’d expect the ORM commands to be working
Looks like the SQL Generator doesn’t produce the correct DDL.