JPA (Eclipselink) #OneToMany misses some entrys - java

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;
}

Related

Problems with Hibernate Mapping

I'm having problem with mapping two classes with composite keys.
The first class is Product:
#Entity
#Table(name = "Products")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#SuperBuilder
public class Product {
#EmbeddedId
private ProductKey prodPK;
#Column(name = "name", length = 50, nullable = false)
private String name;
#Column(name = "description", length = 80)
private String description;
#Column(name = "totalStock", columnDefinition = "double(8,2) default 0")
private double totalStock;
#ManyToOne
#JoinColumn(name = "companyId", referencedColumnName = "id", nullable = false)
private Company company;
}
With this #EmbeddedId:
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Embeddable
public class ProductKey implements Serializable {
#Column(name = "sku", length = 50)
private String sku;
#Embedded
private LotKey lot;
}
At the same time, this embedded class has as part of its composite key another composite key "LotKey"
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Embeddable
public class LotKey implements Serializable {
#Column(name = "lot")
private String lot;
#ManyToOne
#JoinColumn(name = "company", referencedColumnName = "id")
private Company company;
}
which belongs to the class:
#Entity
#Table(name = "Lots")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#SuperBuilder
public class Lote {
#EmbeddedId
private LotKey lotpk;
#Column(name = "stock")
private double stock;
#Column(name = "expirationDate", columnDefinition = "default current_timestamp()")
private Date expirationDate;
}
But I'm having trouble referencing to them:
#Entity
#Table(name = "quantityProduct")
public class QuantityProduct{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#ManyToOne
#JoinColumns({
#JoinColumn(
name = "sku",
referencedColumnName = "sku"),
#JoinColumn(
name = "lot")
})
private Product product;
#Column(name = "quantity", columnDefinition = "double(8,2) default 0")
private double quantity;
}
I am getting the following error
image
Thank you so much !
In QuantityProduct, set also referencedColumnName in
#JoinColumn(
name = "lot")

Issue on hibernate oneToMany with spring boot and postgres

I have an issue with hibernate and postgres using spring boot.
When I run the application I see in postgres logs these errors(without any data bootstrap):
2021-06-25 13:55:31.057 UTC [81] ERROR: constraint "uk_j1xiaxeat9b5r1qs27ei0t2a6" of
relation "process_template_base_environmental_impact" does not exist
2021-06-25 13:55:31.057 UTC [81] STATEMENT: alter table
process_template_base_environmental_impact drop constraint
UK_j1xiaxeat9b5r1qs27ei0t2a6
2021-06-25 13:55:31.062 UTC [81] ERROR: constraint "uk_9568qjc94suvuskoi9o2li3er" of
relation "process_template_elementary_flow_template" does not exist
2021-06-25 13:55:31.062 UTC [81] STATEMENT: alter table
process_template_elementary_flow_template drop constraint
UK_9568qjc94suvuskoi9o2li3er
2021-06-25 13:55:31.064 UTC [81] ERROR: constraint "uk_dy1ej2j9qxeoq6ca641tpfxr5" of
relation "process_template_flow_template" does not exist
2021-06-25 13:55:31.064 UTC [81] STATEMENT: alter table
process_template_flow_template drop constraint UK_dy1ej2j9qxeoq6ca641tpfxr5
I have an entity called ProcessTemplate with ProcessTemplateId as compositeKey, and 3 cascades on ElementaryFlowTemplate, BaseEnvironmentalImpact, and FlowTemplate.
ProcessTemplate:
#Data
#Entity
#EqualsAndHashCode(onlyExplicitlyIncluded = true)
#Table(name = "process_template")
public class ProcessTemplate {
#EmbeddedId
#EqualsAndHashCode.Include
private ProcessTemplateId id;
#ManyToOne
#JoinColumn(name = "fk_process_base", referencedColumnName = "id")
private ProcessBase processBase;
#ManyToOne
#JoinColumn(name = "fk_reference_flow_base", referencedColumnName = "id")
private FlowBase referenceProduct;
#OneToMany(cascade = CascadeType.ALL)
private Set<BaseEnvironmentalImpact> baseEnvironmentalImpacts;
#OneToMany(cascade = CascadeType.ALL)
#OrderBy("impactsContribute DESC" )
private Set<FlowTemplate> flowsTemplate;
#OneToMany(cascade = CascadeType.ALL)
#OrderBy("impactsContribute DESC" )
private Set<ElementaryFlowTemplate> elementaryFlowsTemplate;
#ManyToOne
#JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
#Column(name = "version")
#Version
private Long version;
}
ProcessTemplateId:
#Embeddable
public class ProcessTemplateId implements Serializable {
#Column(name = "process_base_id")
private UUID processBaseId;
#Column(name = "reference_product_id")
private UUID referenceProductId;
public ProcessTemplateId() {
}
public ProcessTemplateId(UUID processBaseId, UUID referenceProductId) {
this.processBaseId = processBaseId;
this.referenceProductId = referenceProductId;
}
public UUID getProcessBaseId() {
return processBaseId;
}
public UUID getReferenceProductId() {
return referenceProductId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ProcessTemplateId)) return false;
ProcessTemplateId that = (ProcessTemplateId) o;
return Objects.equals(getProcessBaseId(), that.getProcessBaseId()) &&
Objects.equals(getReferenceProductId(), that.getReferenceProductId());
}
#Override
public int hashCode() {
return Objects.hash(getProcessBaseId(), getReferenceProductId());
}
}
AbstractFlowTemplate:
#Data
#EqualsAndHashCode(onlyExplicitlyIncluded = true)
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractFlowTemplate {
#Id
#EqualsAndHashCode.Include
private String id;
#Enumerated(EnumType.STRING)
private FlowType flowType;
#ManyToOne
#JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
#Column(name = "version")
#Version
private Long version;
}
ElementaryFlowTemplate:
#Data
#Entity
#EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
#Table(name = "elementary_flow_template")
public class ElementaryFlowTemplate extends AbstractFlowTemplate {
#ManyToOne
#JoinColumn(name = "fk_elementary_flow_base", referencedColumnName = "id")
private ElementaryFlowBase elementaryFlowBase;
}
FlowTemplate (linkedProcessTemplate is not the bidirectional relation to ProcessTemplate but another unidirectional relation, because each flowTemplate had a link to another ProcessTemplate):
#Data
#Entity
#EqualsAndHashCode(callSuper = true, onlyExplicitlyIncluded = true)
#Table(name = "flow_template")
public class FlowTemplate extends AbstractFlowTemplate {
#ManyToOne
#JoinColumn(name = "fk_flow_base", referencedColumnName = "id")
private FlowBase flowBase;
#ManyToOne(cascade = CascadeType.MERGE)
#JoinColumns({#JoinColumn(name = "process_base_id", referencedColumnName =
"process_base_id"),
#JoinColumn(name = "reference_product_id", referencedColumnName =
"reference_product_id")})
private ProcessTemplate linkedProcessTemplate;
}
BaseEnvironmentalImpact:
#Data
#Entity
#EqualsAndHashCode(onlyExplicitlyIncluded = true)
#Table(name = "base_environmental_impact")
public class BaseEnvironmentalImpact {
#Id
#EqualsAndHashCode.Include
private String id;
private double value;
#ManyToOne
#JoinColumn(name = "fk_methodology", referencedColumnName = "id")
private Methodology methodology;
#ManyToOne
#JoinColumn(name = "fk_impact_category", referencedColumnName = "id")
private ImpactCategory impactCategory;
#ManyToOne
#JoinColumn(name = "fk_impact_indicator", referencedColumnName = "id")
private ImpactIndicator impactIndicator;
#ManyToOne
#JoinColumn(name = "fk_source_info", referencedColumnName = "id")
private SourceInfo sourceInfo;
#Column(name = "version")
#Version
private Long version;
//ref
#ManyToOne
#JoinColumn(name = "fk_elementary_flow_base")
private ElementaryFlowBase elementaryFlowBase;
#ManyToOne
#JoinColumns({
#JoinColumn(
name = "process_base_id",
referencedColumnName = "process_base_id"),
#JoinColumn(
name = "reference_product_id",
referencedColumnName = "reference_product_id")
})
private ProcessTemplate processTemplate;
}
As I wrote I cannot understand why I had an errors log, probably I make a mistake in the relation or cascade but I'm not able to figure out the issue. If I import data they seem correctly inserted so I cannot understand the problem.
Thanks in advance for the help.
SOLVED, EDIT:
I solve only the error on ProcessTemplate-BaseEnvironmentalImpact adding a mappedBy.
I don't include a schema because I think it's autogenerated, I include these parameters in application properties:
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation = true
spring.jpa.hibernate.ddl-auto = create-drop
logging.level.org.hibernate = ERROR
spring.jpa.generate-ddl = true
I also solved other issues adding:
#JoinColumns({
#JoinColumn(name = "fk_pt_process_base_id", referencedColumnName = "process_base_id"),
#JoinColumn(name = "fk_pt_reference_product_id", referencedColumnName = "reference_product_id")
} )

Merging two foreign key columns into EmbeddedID

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;

java/hibernate - how to map three tables/entities with annotation (hibernate error not mapped to a single property)

Please help!!. There are three tables
customer, order,order_details
One customer can have many orders and one order has one customer.
One order can have many order details and one order detail has one order.
Following my classes.
OrderDetail.java
#Entity
public class OrderDetail {
#EmbeddedId
private OrderDetail_PK orderDetail_PK;
private int qty;
private double unitPrice;
#ManyToOne
#JoinColumn(name="orderId", referencedColumnName = "id", insertable = false, updatable = false)
private Order order;
#ManyToOne
#JoinColumn(name="itemCode", referencedColumnName = "code", insertable = false, updatable = false)
private Item item;
...
..
OrderDetail_PK.java
#Embeddable
public class OrderDetail_PK implements Serializable{
private String orderId;
private String itemCode;
..
..
Order.java
#Entity
#Table(name="`Order`")
public class Order {
#EmbeddedId
private Order_PK order_PK;
#Id
private String id;
#Temporal(TemporalType.DATE)
private Date date;
#ManyToOne
#JoinColumn(name="customerId", referencedColumnName = "customerId", insertable = false, updatable = false)
private Customer customer;
#OneToMany(mappedBy = "order", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<OrderDetail> orderDetails = new ArrayList<>();
..
..
Order_PK.java
#Embeddable
public class Order_PK implements Serializable{
private String Id;
private String customerId;
..
..
cusotomer.java
#Entity
public class Customer {
#Id
#Column(name = "customerId")
private String id;
private String name;
private String address;
#OneToMany(mappedBy = "customer", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Order> orders = new ArrayList<>();
#OneToMany(mappedBy = "customer", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Payment> payments = new ArrayList<>();
..
..
What is wrong with my code? I need quick help.
Since you are using composite keys, you need to define all relevant join columns:
#Entity
public class OrderDetail {
#ManyToOne
#JoinColumns({
#JoinColumn(name="orderId", referencedColumnName = "id", insertable = false, updatable = false),
#JoinColumn(name="customerId", referencedColumnName = "id", insertable = false, updatable = false),
})
private Order order;

JPA unidirectional one to many with join table - entity mapping not working

I have tried to create some JPA Entities for a DB designed with the following tables: PRINCIPALS and CREDENTIALS which have the following relations with other tables:
#Entity
#Table(name = "CREDENTIALS")
public class Credentials {
#Id
#Column(name = "CREDENTIAL_ID")
private Integer credentialID;
#Id
#Column(name = "CREDENTIAL_TYPE_ID")
private String credentialTypeID;
#OneToOne
#JoinColumn(name = "CREDENTIAL_TYPE_ID", insertable = false, updatable = false)
private CredentialTypes credentialTypes;
}
CREDENTIALS has a oneToOne relation with CREDENTIAL_TYPES
#Entity
#Table(name = "CREDENTIAL_TYPES")
public class CredentialTypes {
#Id
#Column(name = "CREDENTIAL_TYPE_ID")
private String credentialTypeID;
#Column(name = "DESCRIPTION")
private String description;
}
#Entity
#Table(name = "PRINCIPALS")
public class Principals implements Serializable {
#Id
#Column(name = "PRINCIPAL_TYPE_ID", nullable = false)
private String principalTypeID;
#Column(name = "PRINCIPAL_ID", nullable = false)
private String principalID;
#OneToOne
#JoinColumn(name = "PRINCIPAL_TYPE_ID", insertable = false, updatable = false)
private PrincipalTypes principalTypes;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "PRINCIPAL_CREDENTIAL",
joinColumns = #JoinColumn(name = "CREDENTIAL_ID"),
inverseJoinColumns = #JoinColumn(name = "PRINCIPAL_ID"))
private List<Credentials> credentials;
PRINCIPALS has a oneToOne relation with PRINCIPAL_TYPES
#Entity
#Table(name = "PRINCIPAL_TYPES")
public class PrincipalTypes implements Serializable {
#Id
#Column(name = "PRINCIPAL_TYPE_ID", nullable = false)
private String principalTypeID;
#Column(name = "DESCRIPTION")
private String description;
And finally PRINCIPALS has a oneToMany relation with CREDENTIALS and uses a join table PRINCIPLE_CREDENTIAL
#Entity
#Table(name = "PRINCIPAL_CREDENTIAL")
public class PrincipalCredential implements Serializable {
#Id
#Column(name = "PRINCIPAL_TYPE_ID", nullable = false)
private String principalTypeID;
#Id
#Column(name = "PRINCIPAL_ID", nullable = false)
private String principalID;
#Id
#Column(name = "CREDENTIAL_ID")
private Integer credentialID;
#Id
#Column(name = "CREDENTIAL_TYPE_ID")
private String credentialTypeID;
At startup (using SpringBoot) I receive an error for the oneToMany relation between Principals and Credentials and just don't have any idea how to fix it... Tried various other methods (The DB design cannot be changed).
Caused by: org.hibernate.AnnotationException: A Foreign key refering entities.Principals from entities.Credentials has the wrong number of column. should be 2
at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:502)
at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1467)
at org.hibernate.cfg.annotations.CollectionBinder.bindManyToManySecondPass(CollectionBinder.java:1233)
at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:794)
at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:729)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:85
I find the exception wierd because there is no refering of Principlas from Credentials....
PRINCIPLE_TYPE_ID and CREDENTIAL_TYPE_ID are missing in the joinColumns/inverseJoinColumns. I think you must use the #JoinColumns Annotation

Categories

Resources