Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property customer invoice - jpa

I am new to spring based project,
I have the requirement to create the entity relationship mapping between orders and invoices with OneToMany, and tried below mappings, but ending up with mapping error,
Could you please point me out to fix this issue.
#Entity
#Table(name="Customers")
public class Customers implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "CustomerId", nullable = false)
private Long CustomerId;
#OneToMany(cascade=CascadeType.ALL, mappedBy="Customers")
private Set<Orders> Orders = new HashSet<Orders>();
}
#Entity
#Table(name="Orders")
public class Orders implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "orderId", nullable = false)
private Long orderId;
#JoinColumn(name="CustomerId")
#ManyToOne
private Customers customers;
#OneToOne (optional=false,cascade=CascadeType.ALL, mappedBy="orders",targetEntity=Invoices.class)
private Invoices invoices;
}
#Entity
#Table(name="Invoices")
public class Invoices implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "invoiceId", nullable = false)
private Long invoiceId;
#OneToOne(optional=false,cascade=CascadeType.ALL, mappedBy="invoices",targetEntity=Orders.class)
private Orders orders;
}
Error message:
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.mycompany.myproject.persist.entity.Orders.Customers in com.mycompany.myproject.persist.entity.Customers.Orders

Probably because Orders has a property 'customers' and not 'Customers' (as specified by the 'mappedBy' attribute).
You should tidy up your class names and fields as below:
#Entity
#Table(name="Customers")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "CustomerId", nullable = false)
private Long customerId;
#OneToMany(cascade=CascadeType.ALL, mappedBy="customer")
private Set<Order> orders = new HashSet<Order>();
}
#Entity
#Table(name="Orders")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "orderId", nullable = false)
private Long orderId;
#ManyToOne
#JoinColumn(name="CustomerId")
private Customer customer;
#OneToOne(optional=false, cascade=CascadeType.ALL, mappedBy="order")
private Invoice invoice;
}
#Entity
#Table(name="Invoices")
public class Invoice implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GenericGenerator(name = "generator", strategy = "increment")
#GeneratedValue(generator = "generator")
#Column(name = "invoiceId", nullable = false)
private Long invoiceId;
#OneToOne(optional=false,cascade=CascadeType.ALL)
#JoinColumn(name = "InvoiceId")
private Order order;
}

Related

JPA Composite Key: Avoid Unnecessary of Table Creation

I am learning JPA.
I need to create 3 tables, product (pk => id), cart (pk => id), cart_details (pk also fk => product_id, cart_id).
The relation is : One cart can contain multiple cart_details, one cart_details can contain multiple product and one product can be put on multiple cart_details. I need only 3 tables, but JPA creates 4 tables for me: product, cart, cart_details, cart_details_product
#Entity
#Table(name = "product")
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#NotBlank
#Size(max = 50)
private String name;
#Size(max = 300)
private String description;
#NotNull
private Double price;
private int qty;
#Column(name = "created_date")
private Date createdDate;
#Column(name = "updated_date")
private Date updatedDate;
}
#Entity
#Table(name = "cart")
public class Cart implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "total_price")
private double totalPrice;
#Column(name = "created_date")
private Date createdDate;
#Column(name = "updated_date")
private Date updatedDate;
}
#Entity
#Table(name = "cart_details")
public class CartDetails implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private CartDetailsId id;
#MapsId("cartId")
#ManyToOne
#JoinColumn(name = "cart_id", referencedColumnName = "id", insertable = false, updatable = false)
private Cart cart;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "product_id", referencedColumnName = "id")
private Set<Product> product;
private int quantity;
private double price;
}
#Embeddable
public class CartDetailsId implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "cart_id")
private Long cartId;
#Column(name = "product_id")
private Long productId;
}
How to avoid creation of this table (cart_details_product)? I think i don't need this table.

Revision contains null values of other fields if change the #oneToMany - entity by adding a new entity

When a new address is added for a person, a new revision should be created. A revision is created, but the remaining fields of the entity in the revision are marked null.
Different and correct:
When I change a name for a person, a revision is created where all fields are entered.
Person Entity:
#Entity
#Table(name = "Person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Audited
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#OneToMany(mappedBy="person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Person Audit Entity:
#Entity
#Table(name = "person_aud")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class PersonAud implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private AuditIdentity auditIdentity;
#Column(name = "revtype")
private Short revtype;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#ManyToOne
#MapsId("auditIdentity.id")
#JoinColumn(name = "id", nullable = false)
private Person person;
#OneToMany
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Address Entity:
#Entity
#Table(name = "address")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Audited
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
private Long id;
#Column(name = "street")
private String street;
#Column(name = "house_number")
private String houseNumber;
#Column(name = "zip_code")
private String zipCode;
#Column(name = "city")
private String city;
#Column(name = "state_province")
private String stateProvince;
#Column(name = "country")
private String country;
#ManyToOne
#JsonIgnoreProperties("addresses")
private Person person;
#OneToOne
#JsonIgnoreProperties("addresses")
#NotAudited
private PersonAud personAud;
If I add a new address that belongs to person XY, then my table looks like this:
PERSON_AUD:
ID: 1
REV: 1001
REVTYPE: 1
FIRST_NAME: NULL
LAST_NAME: NULL
For example, if I change the first name, the fields for the first_name and last_name are entered.
Problem solved (not perfect):
I changed the line:
#OneToMany(mappedBy="person")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
to:
#OneToMany(cascade = {CascadeType.ALL})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Address> addresses = new HashSet<>();
Now the process works like:
Add a new person with empty Address array
Add a new Address which refers to the person id
Action like a PUT on this Person assigning the address-object.
= PERSON_AUD table will contain the revision and the fields.
PROBLEM:
it is not perfect because you have to assign the address manually to the person.
Is there any other possible solution?

JPA Entity mapping for join columns

I have three tables EmployeeDepartment, EmployeeGroup and EmpplyeeDetails Table. EmployeeDepartment table has primary key departmentId and a column groupId, EmployeeGroupTable has primary key groupid which should be generated from databse sequence GroupIdGenerator.
EmployeeDetails have two primary keys as groupid and employeeid. Groupid should be same as of the previous table
These values in all table should insert in one transaction.
Can you help me with correct JAP Entity mapping?
I already tried with different combination of Generated value and Sequence generator but not able to save the data into table.
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
}
#Coulmn(name="GROUP_ID")
private long groupId;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false ,
updatable=false)
private EmployeeDepartment employeeDepatment;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
#Column(name = "GROUP_ID")
#Nonnull
private Long groupId;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
}
public class EmployeeId{
private Long groupId;
private Long employeeId;
public EmployeeId(final Long groupId, final Long employeeId) {
this.groupId = groupId;
this.employeeId = employeeId;
}
public EmployeeId() {
}
}
Expected result in these 3 tables should have proper values like.
Table EmployeeDepartment
DepartmentID GroupId
1 1
Table EmployeeGroup
GroupID
1
Table EmployeeDetail
GroupId EmployeeId
1 1
1 2
1 3
Actual results are below
Table EmployeeDepartment
DepartmentID GroupId
1 0
Table EmployeeGroup
GroupID
1
Table EmployeeDetail
GroupId EmployeeId
2 1
3 2
4 3
The important annotation is #MapsId("groupId")
Your mapping should be something like this:
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
#Column(name="GROUP_ID")
private long groupId;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false, updatable=false)
private EmployeeDepartment employeeDepatment;
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#MapsId("groupId")
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
#Entity
#Table(name="EMPLOYEE_DEPARTMENT")
public class EmployeeDepartment {
#Column(name = "DEPARTMENT_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"departmentid-gen")
#Id
#NotNull
#SequenceGenerator(name = "departmentid-gen", sequenceName =
"DEAPARTMENT_ID_GENERATOR" )
private Long departmentId;
#OneToOne(mappedBy = "employeeGroup")
private EmployeeGroup employeeGroup;
}
#Column(name="GROUP_ID")
private EmployeeGroup group;
#Entity
#Table(name="EMPLOYEE_GROUP")
public class EmployeeGroup {
#Column(name = "GROUP_ID")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"groupid-gen")
#Id
#NotNull
#SequenceGenerator(name = "groupid-gen", sequenceName =
"GROUIP_ID_GENERATOR" )
private Long groupId;
#OneToMany(mappedBy = "employeeDetail")
private List<EmployeeDetail> employeeDetails;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID", insertable=false ,
updatable=false)
private EmployeeDepartment employeeDepatment;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
#IdClass(EmployeeID.class)
public class EmployeeDetail {
#Id
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
#Id
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
You also need to change the EmployeeId accordingly:
public class EmployeeId{
private EmployeeGroup employeeGroup;
private Long employeeId;
public EmployeeId(final EmployeeGroup employeeGroup, final Long employeeId) {
this.employeeGroup= employeeGroup;
this.employeeId = employeeId;
}
However I haven't use composite keys this way before. If it doesn't work, then change EmployeeId to an embeddedId:
#Embeddable
public class EmployeeId implements Serializable{
#ManyToOne(fetch = FetchType.LAZY, optional = false)
private EmployeeGroup employeeGroup;
#Nonnull
#Column(name = "EMPLOYEE_ID")
private Long employeeId;
public EmployeeId(final EmployeeGroup employeeGroup, final Long employeeId) {
this.employeeGroup= employeeGroup;
this.employeeId = employeeId;
}
#Entity
#Table(name = "EMPLOYEE_DETAIL")
public class EmployeeDetail {
#EmbeddedId
private EmployeeId id;
#ManyToOne
#JoinColumn(name = "GROUP_ID", insertable=false , updatable=false)
private EmployeeGroup employeeGroup;
}
If it still doesn't work, then please attach the code snippet where you create the entities.

org.springframework.dao.InvalidDataAccessResourceUsageException in spring data jpa

i have (one to many) and (many to one) bi-directional mappings while i am querying with #Query with spring- data-jpa using repository using foreign key iam getting InvalidDataAccessApiUsageException
#Entity(name="docket")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Docket implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
#Column(name="docket_Id")
private long Id;
#Column(name="docket_name")
private String docket_name;
#Column(name="area_in_kms")
private long area_in_kms;
#Column(name="number_of_connections")
private long number_of_connections;
#Column(name="number_of_sewer_connections")
private long number_of_sewer_connections;
#Column(name="number_of_manholes")
private long number_of_manholes;
#Column(name="deep_manholes")
private long deep_manholes;
#Column(name="contour_low")
private long contour_low;
#Column(name="contour_high")
private long contour_high;
#Column(name="length_of_sewermain_kms")
private long length_sewer_in_kms;
#JsonBackReference(value="section-details")
#ManyToOne(cascade= CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "section_Id")
private Section section;
#Entity(name="section")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Section implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name="section_Id")
private long Id;
#Column(name="section_name")
private String section_name;
#Column(name="area_in_kms")
private long area_in_kms;
#Column(name="calculated_length")
private long calculated_length;
#Column(name="area_geometry")
private long area_geometry;
//#JsonManagedReference
#OneToMany(mappedBy = "section", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private Set<Docket> docket;
#Repository
#Transactional(readOnly = true)
public interface DocketRepository extends JpaRepository<Docket, Long> {
#Modifying(clearAutomatically = true)
#Query(nativeQuery=true,value= "select d from docket d where d.section_id = :section_id" )
List<Docket> findAlldocketsforsection(#Param("section_id") long id);
need help!! on this i need to query more custom queries in this api please suggest me from where i am getting error

Hashmap with 2 Foreign Keys

How to create a hashmap with 2 foreign keys as reference? Something like, Table 3 have a hashmap that for each table1 id have an id from table2.
#Entity
public class table1 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
...
#Entity
public class table2 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
...
I was trying something like this:
#Entity
public class table3 implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
#ElementCollection
#MapKeyJoinColumn(name = "table1", referencedColumnName = "ID")
#MapKeyJoinColumn(name = "table2", referencedColumnName = "ID")
private Map<table1, table2> hashmap_relation = new LinkedHashMap<table1, table2>();
...