Spring boot JPA DataIntegrityViolationException - java

I have two entity classes, named Product and ComboProduct. Product contains all the information about a particular product and has a Primary Key productId. ComboProduct holds a list with a #OneToMany relationship to the Product and has a primary key named comboProductId. When I create multiple Comboproduct instances with the same set of products, I get the following DataIntegrityViolationException:
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long productId;
#OneToOne
private MasterProduct masterProduct;
#NotBlank
private String productName;
private String productDescription;
private Double productSellingPrice; // mrp
private Double productOfferPrice; // price at which the user sells
private Double productPurchasePrice;
private float totalTaxPercentage;
private float productMargin;
#OneToOne
private MerchantStore store;
#ManyToOne
private ComboProduct comboProduct; #Entity
public class ComboProduct {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long comboProductId;
private String comboProductKey;
#OneToMany
private List<Product> products;
#NotBlank
private String comboName;
private String comboDescription;
org.springframework.dao.DataIntegrityViolationException:
could not execute statement; SQL [n/a];
constraint [UK_nm4dyaqp2f780nx73vq9abbw3];
nested exception is org.hibernate.exception.ConstraintViolationException:
could not execute statement\n\t
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:298)\n\t
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)\n\t
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:538)\n\t
at org.springframework.transaction.support.
How can I resolve this?

as you have modeled a One-to-Many relationship, you defined that one combo is associated to multiple products. But products can only be assigned to one combo.
If you want products to be able to belong to multiple combos, you would need to model a Many-to-Many relationship. That would of course also imply to have a respective mapping table on the database.

Relationships between the 2 entity classes were not established properly.
`
#Entity
public class Product {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private Long productId;
#ManyToOne
private ComboProduct comboProduct; }
#Entity
public class ComboProduct {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long comboProductId;
#OneToMany
private List<Product> products;
} `

The problem is you need to tell Hibernate that the OneToMany mapping will use a foreign key on another table, otherwise, it will assume that the entity in the list must have a unique Id.
To do so, you must add #JoinColumn on the attribute owning the mapping (class ComboProduct attribute products).
Try the following:
#Entity
public class ComboProduct {
...
#OneToMany(mappedBy = "comboProduct")
private List<Product> products;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long productId;
private String productDescription;
private Double productSellingPrice;
private Double productOfferPrice;
#ManyToOne
#JoinColumn
private ComboProduct comboProduct;
}

Related

How to make a query which searches by myClass_id and by either teacher_id or by replacingTeachers' ids (to contain an id) with Spring JPA?

I have an entity Subjects:
public class Subject {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
#OneToOne
private Teacher teacher;
#ManyToMany
private Set<Teacher> replacingTeachers;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "class_id")
private Class myClass;
}
And I want to make a query which searches by myClass_id and by either teacher_id or by replacingTeachers' ids (to contain an id). How to do this with Spring JPA? I tried this:
Optional<Subject> findByTeacherIdAndMyClassIdOrReplacingTeachersContains(final Long teacherId, final Long classId);

JPA StackOverflow -- Many to Many and one to one mapping

I am trying to save a JPA entity which has ManytoMany Relationship (Consumer and Product table) and OnetoOne relation with ConsumerDetailstable.Below are my entities
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class)
#Entity
public class Consumer {
#Id
#GeneratedValue
private Long id;
private String firstName;
private String lastName;
#JsonManagedReference
#OnToMany(mappedBy = "consumer")
private Set<ConsumerProduct> consumerProducts;
#OneToOne
private CustomerDetails consumerDetails;
}
#Entity
public class Product {
#Id
#GeneratedValue
private Long productId;
private String productCode;
#OneToMany(mappedBy = "product")
private Set<ConsumerProduct> consumerProducts;
}
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class)
#Entity(the join table)
public class ConsumerProduct {
#EmbeddedId
ConsumerProductKey id;
#JsonBackReference
#ManyToOne
#MapsId("id")
#JoinColumn(name = "id")
private Consumer consumer;
#ManyToOne
#MapsId("productId")
#JoinColumn(name = "product_id")
private Product product;
}
#Embeddable (forgein keys combined as embeded id)
public class ConsumerProductKey implements Serializable {
#Column(name="id")
private Long id;
#Column(name = "product_id")
private Long productId;
}
#Enitity (one to one relation table)
public class CustomerDetails {
#Id
#GeneratedValue
private Long consumerDtlId;
#OneToOne
private Consumer consumer;
private String city;
private String state;
private String country;
}
To save the entity am have just extended JPARepository and called save method
public class ConsumerRepository<Consumer> Implements JPARepository<Consumer, Long> {
#Override
public Consumer S save(Consumer entity) {
return save(entity);
};
}
I get java.lang.StackOverFlowError at save method.
Anything wrong with my Mappings ?
Question: Since this will be save operation and since Consumer Id is yet to be generated how do I assign to below Entities
ConsumerProduct.ConsumerProductKey (how do i assign Id of consumer table once it is inserted to join table ? will JPA take care of it)
CustomerDetails (how do i assign Id of consumer table once it is inserted to join table ? will JPA take care of it)
EDIT: I have updated the entity with JsonManagedReference and JsonBackedReference but still i have am facing stackoverflow error
It is due to Consumer trying to access ConsumerProduct and ConsumerProduct trying to access consumer entity and end up with StackOverflow error.
You should use #JsonManagedReference and #JsonBackReference annotation in consumer and ConsumerProduct respectivly.

How to create Spring Entity and Repository without primary key

I have a table with two columns user_id and role_id. There's no unique column in table and I can't add one. How can I create Entity and Repository in Spring without a primary key?
This is my UserRole.class
public class UserRole {
#Column(name = "user_id")
private int userId;
#Column(name = "role_id")
private int roleId;
//getters and setters
}
But with this class i get the following error:
nested exception is org.hibernate.AnnotationException: No identifier specified for entity:
I saw that one of the answers is to use all of the columns as the id, but i have no idea how to do it.
Please see the awnser in this post. This should help you.
PK Explained
Another Option is if this is a join table, than you could make Embeded PK
#Embeddable
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder(toBuilder = true)
public class PersonGroupPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
#Column(insertable=false,unique = false, updatable=false, nullable=false)
private Long personId;
#Column(insertable=false, unique = false,updatable=false, nullable=false)
private Long groupId;
}

How to store amount of objects in Spring data

Description
I have a system where I can add Component and save it to DB(Mysql). After that a can create Product which contains Components in different amount.
As I understand table should be like component_id|product_id|amount_of_component
Component class:
#Entity
#Table(name = "component")
public class Component {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
}
Product class:
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
//something should be here
private Component component;
}
Question
Which annotation or Collection I should use to create such relations between that entities ?
You must use OneToMany with either Set or List. Here is an example:
#OneToMany
#JoinColumn("product_id")
private Set<Component> component;
Please read the Hibernate documentation about Collection mapping: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#collections

How to adjust relations between entities using Hibernate mapping?

I have such a simple scheme
and the following entities:
#Entity
public class Ticket {
#Id
#GeneratedValue
private Integer id;
#ManyToOne
private Event event;
#OneToOne
private User user;
#Embedded
private Seat seat;
private TicketState state;
private Float price;
// getters, setters, etc.
#Entity
public class Event {
#Id
#GeneratedValue
private Integer id;
#OneToOne
private Movie movie;
#Embedded
private Auditorium auditorium;
private LocalDateTime startDateTime;
#OneToMany
private Set<Ticket> tickets = new HashSet<>();
// getters, setters, etc.
#Entity
public class User {
#Id
#GeneratedValue
private Integer id;
#Enumerated(EnumType.STRING)
private UserRole role;
private String name;
private String email;
private Instant birthday;
#OneToMany
private List<Ticket> tickets = new ArrayList<>();
private boolean lucky;
// getters, setters, etc.
#Embeddable
public class Auditorium {
private Integer id;
private String name;
private Integer seatsNumber;
#ElementCollection
private List<Integer> vipSeats;
// getters, setters, etc.
Also these entities was added to hibernate.cfg.xml.
Than I run app I have the following exception:
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.epam.spring.core.domain.Event column: id (should be mapped with insert="false" update="false")
At first glance I don't see any duplications in Event, as mentioned in exception. What should I fix in entities mapping description to resolve the problem according my scheme? Thank you!
Both Event and Auditorium map to column named id.
Specify a different column name in Auditorium or use #AttributeOverride in Event to override the default name.
When you map an entity with annotations, you do not need to repeat yourself on hibernate.cfg.xml. Try to delete it e run your code again.
Updating my answer based on Dragan Bozanovic's, Auditorium should NOT have an #Id annotated field (but we can't see that from your code, if it has).

Categories