JPA adding insert for manyToMany table - mysql

I have got two entity. Employee and Project
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.*;
import lombok.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity
#Table(name = "EMPLOYEE_DB")
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int emp_id;
private String name;
private String email;
private String phone;
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinTable(name = "EMP_PRO_DB", joinColumns = {
#JoinColumn(name = "empId", referencedColumnName = "emp_id")
},
inverseJoinColumns = {
#JoinColumn(name = "proId", referencedColumnName = "pro_id")
}
)
// #JsonManagedReference
private Set<Project> projects;
}
and
import com.fasterxml.jackson.annotation.JsonBackReference;
import jakarta.persistence.*;
import lombok.*;
import java.util.Set;
#Entity
#Table(name = "PROJECT_DB")
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int pro_id;
private String projectName;
private String projectType;
#ManyToMany(mappedBy = "projects", fetch = FetchType.LAZY)
#JsonBackReference
private Set<Employee> employees;
}
So there were three tables created:
employee_db
project_db
emp_pro_db
I have a EmployeeRepo and ProjectRepo. I can add data to both employee_db and project_db.
Now I would like to assignProject.
I have tried using workbench to insert: INSERT INTO emp_pro_db (emp_id, pro_id) VALUES (1, 6);
Which is working.
How do I use Jpa to do that?

Related

How to delete/update by querying on JPA interface?

The Item table has Many to One relationship with supplier table.
If i delete supplier table row data by Id, its not deleting the row.
The Item table has many rows with same supplier Id. If i delete in supplier table with id, the item table supplier column data /id should be deleted.
Thanks in advance
Item
package com.ingroinfo.ubm.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "master_item")
#SequenceGenerator(name = "item_sequence", initialValue = 201, allocationSize = 10000)
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "branch_sequence")
private Long itemId;
private String itemName;
private String itemImage;
private String itemStatus;
private String unitOfMeasure;
private String remarks;
private String units;
#ManyToOne
#JoinColumn(name = "category_id")
private Category category;
#ManyToOne
#JoinColumn(name = "supplier_id")
private Supplier supplier;
#ManyToOne
#JoinColumn(name = "brand_id")
private Brand brand;
#ManyToOne
#JoinColumn(name = "publisher_id")
private BrandPublisher publisher;
#ManyToOne
#JoinColumn(name = "hsn_id")
private HsnCode hsnCode;
#Column(name = "date_created")
#CreationTimestamp
private Date dateCreated;
#Column(name = "last_updated")
#UpdateTimestamp
private Date lastUpdated;
}
ItemRepository
package com.ingroinfo.ubm.dao;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.ingroinfo.ubm.entity.Item;
#Repository
#Transactional
public interface ItemRepository extends JpaRepository<Item, Long> {
Item findByItemId(Long id);
#Modifying
#Query("UPDATE Item i SET i.supplier= :val WHERE i.supplier = :id")
void deleteSupplierId(#Param("val") String val, #Param("id") Long id);
}
MasterService
void deleteItemSupplierId(String val, Long id);
MasterServiceImpl
#Override
public void deleteItemSupplierId(String val, Long id) {
itemRepository.deleteSupplierId(val, id);
}
MasterController
#GetMapping("/supplier/delete")
public String deleteSupplier(#RequestParam Long supplierId) {
masterService.deleteItemSupplierId(null, supplierId);
masterService.deleteBySupplierId(supplierId);
return "redirect:/master/supplier/list?supplierDeleted";
}
You can do that by using cascade types, for example
#OneToMany(cascade = CascadeType.REMOVE)

Itirate over a list and filter specific data coming from JSON then save to MySQL

I have these entities: ReleveBancaireEntity LigneReleveEntity OperationCreditEntity and these transactions entities OperationChequeEntity OperationVirementEntity and OperationEspeceEntity
So my ReleveBancaireEntity has a list of LigneReleveEntity and OperationCreditEntity has inheritance of type single table and all transactions entities extends from OperationCreditEntity, my goal is to verify and filter LigneReleveEntity based on a field called private String creditDebit; and see if it has letter D I should ignore it and don't persist it, and if it has letter C I want to persist it to the database OperationCreditEntity
Here are my entites:
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#Table(name = "RELEVEBANCAIRE")
#Entity
#ToString
#Builder
public class ReleveBancaireEntity{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long releveBancaireId;
#CreationTimestamp
#Temporal(TemporalType.DATE)
private Date dateReception;
private String label;
private int nbrLignes;
private int nbrOperationCredit;
private int nbrOperationDebit;
private BigDecimal soldeInitial;
private BigDecimal soleFinal;
#OneToMany(cascade= CascadeType.ALL,mappedBy = "releveBancaire", fetch = FetchType.EAGER)
#JsonIgnoreProperties("releveBancaire")
#JsonIgnore
private List<LigneReleveEntity> lignereleve = new ArrayList<>();
=================================
#Table(name = "LIGNERELEVE")
#Entity
#Getter
#Setter
#AllArgsConstructor(access = AccessLevel.PUBLIC)
#NoArgsConstructor(access = AccessLevel.PUBLIC)
#ToString
public class LigneReleveEntity{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long ligneReleveId;
#CreationTimestamp
#Temporal(TemporalType.DATE)
private Date dateOperation;
private String operationNature;
private BigDecimal montant;
private String creditDebit;
// String creditDebit
private int ref;
private int refPaiment;
private String modePaiment;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "FK_releveBancaire", referencedColumnName = "releveBancaireId")
#JsonIgnoreProperties("lignereleve")
private ReleveBancaireEntity releveBancaire;
==============================
#Getter
#Setter
#Table(name = "OPERATIONCREDIT")
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#AllArgsConstructor
#NoArgsConstructor
public class OperationCreditEntity {
#Id
#Column(nullable = false, updatable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long operationCreditId;
#CreatedDate
private Date operationDate;
#OneToOne
private LigneReleveEntity ligneReleve;
===============================
#Getter
#Setter
#Entity
#AllArgsConstructor
#NoArgsConstructor
#DiscriminatorValue("Operation_Especes")
public class OperationEspecesEntity extends OperationCreditEntity {
private String cin;
private String nomEmetteur;
private String prenomEmetteur;
=============================
#Getter
#Setter
#Entity
#AllArgsConstructor
#NoArgsConstructor
#DiscriminatorValue("Operation_Virement")
public class OperationVirementEntity extends OperationCreditEntity {
private String rib;
===========================
#Getter
#Setter
#Entity
#AllArgsConstructor
#NoArgsConstructor
#DiscriminatorValue("Operation_Cheque")
public class OperationChequeEntity extends OperationCreditEntity{
private int numeroCheque;
And this is OperationCreditEntity(SINGLE TABLE) table on MySQL:

the table "stock" doesn't exist jpa and spring-boot

Everything was working well until I use the annotation #ManyToOne in the class 'Stock', it generates the error:
"Caused by: java.sql.SQLSyntaxErrorException: Table 'libraries.stock' doesn't exist"
the implementation of the class "Stock":
import java.util.List;
import javax.persistence.*;
import lombok.Data;
#Entity
#Table(name="stock")
#Data
public class Stock {
#EmbeddedId
private stockid id;
private int quantity;
public Stock(int qq) {
this.quantity = qq;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "book_id")
private Book book ;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "library_id")
private Library library ;
}

generated primary key for secondary table coming null on #OneToMany relationship

I'm trying to do a simple #OneToMany relationship between contract and asset. But when hibernate tries to save , it's comming as null. What am I doing wrong?
#Entity
#Data
#EqualsAndHashCode
#NoArgsConstructor
#Table(name = "contracts")
public class Contract {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "contractId")
private List<Asset> assets;
}
#Entity
#Data
#Table(name = "assets")
public class Asset {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#ManyToOne
#JoinColumn(name = "contractId", referencedColumnName = "id")
private Contract contractId;
}
#Repository
public interface ContractRepository extends CrudRepository<Contract, Integer> {
}
private void mapAndSave(ContractDTO contractDTO) {
Contract contractToSave = new Contract();
ModelMapper mapper = BiModelMapper.createModelMapperDtoToEntity();
mapper.map(contractDTO, contractToSave);
contractRepository.save(contractToSave);
}
Caused by: java.sql.SQLIntegrityConstraintViolationException: Column 'contractId' cannot be null
The solution I was able to do is change my column table Asset.contractId to NOT NULL. Because Hibernate tries to insert the row, and after that updates the contractId.
And I change to unidirectional relationship, using only #OneToMany on Contract side.

Duplicate results with Hibernate, Spring, MySQL 5.7, Lombok

I have simple code like:
#Transactional(readOnly = true, timeout = 10)
public List<MyClass> findThem() {
Criteria criteria = getSession().createCriteria(MyClass.class);
#SuppressWarnings("unchecked")
List<MyClass> theList = criteria.list();
return theList;
}
When I use this for the query, I get back 942 items, with duplicated items in the list. I don't see the pattern about which ones are duplicated just yet.
If I query with DB directly, I get back 138 records. 138 is the correct number of results:
SELECT count(*) FROM theschema.MY_CLASS;
I tried using the class with and without Lombok's #EqualsAndHashCode(exclude="id") on MyClass and also just not including any equals() implementation, thinking this was the cause - but no luck.
I've recently upgraded from MySQL 5.6 to MySQL 5.7.17 but I'm still on Hibernate 4.3.8.Final and HikariCP 2.5.1. The query has no WHERE clauses or anything very complicated. It may not matter, but I'm on Spring 4.3.3.RELEASE with mysql-connector-java 5.1.39.
Any other suggestions where to look? I'm going to turn on more debug logging and take a closer look in the meantime.
Update:
I'm able to correct this with criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); but not sure why it's now necessary.
Update 2
Here's MyClass. It has more basic properties, but I excerpted them for brevity. Some of the names are renamed for privacy reasons.
import base.domain.model.Persistable;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.*;
#NoArgsConstructor
#Entity
#Table(name = "MY_CLASS")
public class MyClass implements Persistable {
#Getter
#Setter
#Id
#Column(name = "MY_CLASS_ID")
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Getter
#Setter
private ClassB classb;
#Getter
#Setter
#ManyToOne
#JoinColumn(name = "CLASS_C_ID")
private ClassC classC;
#Getter
#Setter
#Transient
private Integer daysOpen;
#Getter
#Setter
#OneToOne
#JoinColumn(name = "CLASS_D_ID")
private ClassD classD;
#Getter
#Setter
#NotEmpty
private String briefDescription;
#Getter
#Setter
#Column(length = 1000)
private String details;
#Getter
#Setter
#OneToOne
#JoinColumn(name = "COMPANY_ID")
private Company company;
#Getter
#Setter
#Transient
private BigDecimal cost;
#Getter
#Setter
#ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinTable(name = "MY_CLASS_TAG",
foreignKey = #ForeignKey(name = "FK_MY_CLASS_TAG_REQUEST"),
joinColumns = #JoinColumn(name = "MY_CLASS_ID"),
inverseJoinColumns = #JoinColumn(name = "TAG_ID"))
private Set<Tag> tags = new HashSet<>(10);
#Getter
#Setter
#ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinTable(name = "MY_CLASS_ASSIGNEE",
foreignKey = #ForeignKey(name = "FK_MY_CLASS_ASSIGNEE"),
joinColumns = #JoinColumn(name = "MY_CLASS_ID"),
inverseJoinColumns = #JoinColumn(name = "ASSIGNEE_ID"))
private Set<Account> assignees = new HashSet<>(0);
#Getter
#Setter
#OneToMany(cascade = CascadeType.ALL, mappedBy = "myClass")
private List<MyClassHistory> historyList = new ArrayList<>(1);
private static final long serialVersionUID = 1L;
}
Update 3:
I am also able to get the correct results using HQL (abridged) without the result transformer:
String hql = "from MyClass myClass";
Query q = getSession().createQuery(hql);
List<MyClass> myClasses = q.list();
return myClasses;
Going to compare the SQL output for each (there's a lot of output to try to understand).
there must be some join happening in the query, which increases resultset and hence your count,often I face similar issue, you can try to take data in Set instead of list, or observe the actual query fired in DB.