I have two tables (Product and Supermarket). They have Many to Many relationship so I created an additional table ProductSupermarket. I want the last table to have only one column which is merging the two foreign keys. This is what I have implemented so far but I am stuck with two columns in the ProductSupermarket - product_id and supermarket_id ..
Product
#Entity
#Table(name = "product")
public class Product{
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "product_id")
private Long productID;
..
Supermarket
#Entity
#Table(name = "supermarket")
public class Supermarket{
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "supermarket_id")
private Long supermarketID;
...
ProductSupermarketKey
#Embeddable
public class ProductSupermarketKey implements Serializable {
#Column(name="product_id")
private Long productID;
#Column(name="supermarket_id")
private Long supermarketID;
public ProductSupermarketKey (){}
public ProductSupermarketKey (Long productID, Long supermarketID) {
this.productID = productID;
this.supermarketID = supermarketID;
}
ProductSupermarket
#Entity
#Table(name = "date_event")
public class ProductSupermarket implements Serializable {
#EmbeddedId
private ProductSupermarketKey id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "product_id", insertable = false, updatable = false)
private Product product;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "supermarket_id", insertable = false, updatable = false)
private Supermarket supermarket;
Related
I am working on mapping a relationship using a composite key, but the composite key is a separate table.
Car Table
car Id
car description
car Value
SafetyReport Table
safetyReport Id
safetyReport Date
safetyReport Value
CompositeKey CarSafetyReport Table
carid
safetyReportId
One To Many: A car will have many safety reports
JPA:
#Data
#Entity
#Table(name = "CarTable")
public class CarEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "CarId", nullable = false)
private int carId;
#Column(name = "CarDescription", nullable = false)
private String carDescription;
#Column(name = "CarValue", nullable = false)
private String carDescription;
}
#Data
#Entity
#Table(name = "SafetyReport")
public class SafetyReportEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "SafetyReportId", nullable = false)
private int SafetyReportID;
#Column(name = "SafetyReportDate", nullable = false)
private OffsetDataTime date;
#Column(name = "SafetyReportValue", nullable = false)
private String safetyReportValue;
}
#Data
#Entity
#Table(name = "CarSafetyReport")
public class CarSafetyReportEntity implements Serializable {
#EmbeddedId
private CarSafetyReportPk id;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Embeddable
public class CarSafetyReportPk implements Serializable {
#Column(name = "CarId", nullable = false)
private int carId;
#Column(name = "SafetyReportId", nullable = false)
private int SafetyReportId;
}
I tried
public class CarEntity {
#OneToMany(mappedBy = "id.carId" )
private List<CarSafetyReportEntity> carSafetyReportEntity;
}
I also tried putting the relationship in the composite key CarSafetyReportPk but i got an error for the annotation #OneToMany in a composite key.
I have main table merchants and second table terminals:
Merchant table:
#Entity
#Table
public class Merchants {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false, nullable = false)
private int id;
#Column
private String name;
#Column
private String login;
}
Terminal table:
#Entity
#Table
public class Terminals {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", updatable = false, nullable = false)
private int id;
#Column
private int merchant_id;
#Column
private String mode;
}
I want to set merchant_id into table Terminals. I suppose that many to many will be proper relation. How I can create it?
If you have a Join Table:
On Merchants class:
#ManyToMany
#JoinTable(name="MER_TER", joinColumns=#JoinColumn(name="MERCH_ID", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="TERM_ID", referencedColumnName="id"))
private List<Terminals> terminalsList;
On Terminals class:
#ManyToMany(mappedBy="terminalsList")
private List<Merchants> merchantsList;
Page of reference: link
If you don't have a Join Table, try to look here: https://stackoverflow.com/a/25018992
How can I include a referenced table column in a unique constraint? I want to create a unique constraint for table Survey for columns toEmail, receipt.receiptSeries and receipt.receiptNum.
See entities below please:
Receipt
#Entity
#Table(name = "RECEIPT")
public class Receipt {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "RECEIPT_SERIES")
private String receiptSeries;
#Column(name = "RECEIPT_NUM")
private String receiptNum;
}
Survey
#Entity
#Table(name = "SURVEY"}
public class Survey {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "RECEIPT_ID")
private Receipt receipt;
#Column(name = "TO_EMAIL")
private String toEmail;
}
I've tried using the approach below with no success:
#Table(name = "SURVEY", uniqueConstraints = {
#UniqueConstraint(columnNames = {"TO_EMAIL", "RECEIPT.RECEIPT_SERIES", "RECEIPT.RECEIPT_NUM"})})
Using a composite primary key with receiptSeries and receiptNum for Receipt is not an option.
Try something like this
#Table(name="notification_status", uniqueConstraints=
arrayOf(UniqueConstraint(columnNames= arrayOf("external_user_id",
"external_organization_id",
"notification_id"))))
Suppose, we have two entities, first one:
#Entity
#Table(name = "entitya")
public class EntityA {
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private Long name;
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private Set<EntityB> childEntities;
}
and the second:
#Entity
#Table(name = "entityb")
public class EntityB {
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "master")
private Boolean master;
#ManyToOne
#JoinColumn(name = "parent")
private EntityA parent;
}
So far, so good. However underlying database tables and constrains enforce that for any entityA there can be only one EntityB with boolean field master set to true. I can extract it by adding following method to entityA:
public entityB getMasterChild() {
for(entityB ent : childEntities) {
if(ent.isMaster()) {
return ent;
}
}
}
The question is, can I create #OneToOne relationship in EntityA that can express that rule, so that entityA can have additional masterChild member of type entityB?
If I understood you correctly you want to create/define a relationship between two entities based on a value of some entity's property. The think is that relationship between entities is defined on entities count (how many entities can has the other entity) and not on some entity's property value.
However
If you really want to use #OneToOne mapping for masterChild I would recommend creating a separate table/entity for it. Once this is done, you can include this new MasterChild entity into EntityA and annotate it with #OneToOne.
Here is new MasterChild entity
#Entity
public class MasterChild extends EntityB{
#Id
#Column(name = "id")
private Long id;
}
Note that I have removed 'master' from EntityB as it is no longer needed
#Entity
#Table(name = "entityb")
public class EntityB {
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "parent")
private EntityA parent;
}
And here is modified EntityA
#Entity
#Table(name = "entitya")
public class EntityA {
#Id
#Column(name = "id")
private Long id;
#Column(name = "name")
private Long name;
#OneToOne
private MasterChild master;
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private Set<EntityB> childEntities;
}
I got 2 Entities
Customer.class
#Entity
#Table(name = "Customer")
public class Customer {
#Id
private int id;
#OneToMany(mappedBy = "customer"; fetch = FetchType.EAGER)
private Set<Invoice> invoice;
}
and
Invoice.class
#Entity
#Table(name = "Invoice")
public class Invoice {
#Id
#ManyToOne
#JoinColumn(name = "customer")
private Customer customer;
#Column(name = "price", nullable = false)
private double price;
}
They are both mapped in the persistence.xml.
So:
System.out.println(customer);
for a specific customer gives me 30 Invoice entrys, but I got 33 in the Database.
I use org.eclipse.persistence.jpa 2.5.0 and persistence-api 1.0.2
I appreciate every hint/solution.
Thanks in advance.
Sorry for the late reply
I found the problem/answer.
After just trying #EmbeddedId I had to declare the #JoinColumn insertable and updatable false.
The right mapping for the Invoice.class
#Entity
#Table(name = "Invoice")
public class Invoice {
#EmbeddedId
private InvoiceId invoiceId;
#ManyToOne
#JoinColumn(name = "customerId", insertable = false, updatable = false)
private Customer customer;
#Column(name = "price", nullable = false)
private double price;
}
#Embeddable
class InvoiceId implements Serializable {
//Composite PK
#Column(name = "customerId")
private int customerId;
#Column(name = "date")
private Date date;
}