I work on learning app, in fact making relationships between two tables.
User - Base table that can have one primary account
PrimaryAccount - that is also reference to PrimaryTransactions with OnetoMany annotation,
PrimaryTransaction - has reference to PrimaryAccount as many transaction related to primary Account.
Although (as per my perception) I'm mentioning right reference between both class but getting an error as follows. Perhaps error lies because of PrimaryAccount.java doesn't have reference for User.java whereas User.java does have for PrimaryAccount.java.
I wonder that the instructor I follow successful runing his app in this way.
Any help will be appreciated.
Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'entityManagerFactory' defined in class path resource
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation
of init method failed; nested exception is org.hibernate.AnnotationException: #OneToOne or
#ManyToOne on com.userfront.domain.PrimaryTransaction.primaryAccount references an unknown
entity: com.userfront.domain.PrimaryAccount
PrimaryAccount.java
package com.userfront.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.List;
public class PrimaryAccount {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private int accountNumber;
private BigDecimal accountBalance;
#OneToMany(mappedBy = "primaryAccount", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JsonIgnore
private List<PrimaryTransaction> primaryTransactionList;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(int accountNumber) {
this.accountNumber = accountNumber;
}
public BigDecimal getAccountBalance() {
return accountBalance;
}
public void setAccountBalance(BigDecimal accountBalance) {
this.accountBalance = accountBalance;
}
public List<PrimaryTransaction> getPrimaryTransactionList() {
return primaryTransactionList;
}
public void setPrimaryTransactionList(List<PrimaryTransaction> primaryTransactionList) {
this.primaryTransactionList = primaryTransactionList;
}
}
PrimaryTransaction.java
package com.userfront.domain;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
#Entity
public class PrimaryTransaction {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Date date;
private String description;
private double amount;
public PrimaryTransaction() {
}
public PrimaryTransaction(Date date, String description, String type, String status, double amount, BigDecimal availableBalance, PrimaryAccount primaryAccount) {
this.date = date;
this.description = description;
this.amount = amount;
this.primaryAccount = primaryAccount;
}
#ManyToOne
#JoinColumn(name = "primary_account_id")
private PrimaryAccount primaryAccount;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public PrimaryAccount getPrimaryAccount() {
return primaryAccount;
}
public void setPrimaryAccount(PrimaryAccount primaryAccount) {
this.primaryAccount = primaryAccount;
}
}
User.java
package com.userfront.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.List;
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "userId", nullable = false, updatable = false)
private Long userId;
private String username;
private String password;
private String firstName;
private String lastName;
#Column(name = "email", nullable = false, updatable = false)
private String email;
private String phone;
private boolean enable = true;
#OneToOne
private PrimaryAccount primaryAccount;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public PrimaryAccount getPrimaryAccount() {
return primaryAccount;
}
public void setPrimaryAccount(PrimaryAccount primaryAccount) {
this.primaryAccount = primaryAccount;
}
#Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + '\'' +
", password='" + password + '\'' +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
", enable=" + enable +
", primaryAccount=" + primaryAccount +
'}';
}
}
You have to add #Entity annotation to PrimaryAccount
In Spring Data Jpa, you have to annotate the class with #Entity Annotation,That's why the bean is not created and also if you want you can mention #Table annotation to mention the table name.
Related
I'm new to this tool and I'm having trouble with this specific issue. I looked for an example But could not find something similar, better, I found a possible solution, but in my case It doesn't work.
I have this narrow project that resembles our famous CRUD, and I'm trying to reference the primary key from one table to another.
Client Entity:
#Entity
#Table(name = "client")
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "cpf", length = 14)
private String cpf;
#Column(name = "name", length = 100)
private String name;
#Column(name = "birth_date")
private LocalDate birthDate;
#Column(name = "address", length = 255)
private String address;
#Column(name = "telephone", length = 14)
private String telephone;
#Column(name = "email", length = 200)
private String email;
#Column(name = "date_register", insertable = true, updatable = false)
private LocalDate dateRegister;
public Client() {
super();
}
public Client(Long id, String cpf, String name, LocalDate birthDate, String address, String telephone, String email, LocalDate dateRegister) {
super();
this.id = id;
this.cpf = cpf;
this.name = name;
this.birthDate = birthDate;
this.address = address;
this.telephone = telephone;
this.email = email;
this.dateRegister = dateRegister;
}
public Client(String cpf, String name, LocalDate birthDate, String address, String telephone, String email, LocalDate dateRegister) {
super();
this.cpf = cpf;
this.name = name;
this.birthDate = birthDate;
this.address = address;
this.telephone = telephone;
this.email = email;
this.dateRegister = dateRegister;
}
#PrePersist
public void prePersist() {
setDateRegister(LocalDate.now());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public LocalDate getDateRegister() {
return dateRegister;
}
public void setDateRegister(LocalDate dateRegister) {
this.dateRegister = dateRegister;
}
#Override
public String toString() {
return "Client [id=" + id + ", cpf=" + cpf + ", name=" + name + ", birthDate=" + birthDate + ", address="
+ address + ", telephone=" + telephone + ", email=" + email + ", dateRegister=" + dateRegister + "]";
}
}
Sale Entity:
#Entity
#Table(name = "sale")
public class Sale {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#JoinColumn(name = "client_id")
private Client client;
#OneToMany(mappedBy = "sale")
private List<SaleItem> items;
#Column(name = "payment_type", length = 10)
#Enumerated(EnumType.STRING)
private PaymentType paymentType;
#Column(name = "amount")
private BigDecimal amount;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public List<SaleItem> getItems() {
return items;
}
public void setItems(List<SaleItem> items) {
this.items = items;
}
public PaymentType getPaymentType() {
return paymentType;
}
public void setPaymentType(PaymentType paymentType) {
this.paymentType = paymentType;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
#Override
public String toString() {
return "Sale [id=" + id + ", client=" + client + ", items=" + items + ", paymentType=" + paymentType
+ ", amount=" + amount + "]";
}
}
The objective is to link the client to a sale through its primary key. These two codes refer to the sales repository and its controller:
SaleRepository:
public interface SaleRepository extends JpaRepository<Sale, Long> {
}
SaleController:
#RestController
#RequestMapping("/api/sales")
#CrossOrigin("*")
public class SaleController {
#Autowired
private SaleRepository repository;
#Autowired
private SaleItemRepository saleItemrepository;
#PostMapping
#Transactional
public void save(#RequestBody Sale sale) {
repository.save(sale);
sale.getItems().stream().forEach(saleItem -> saleItem.setSale(sale));
saleItemrepository.saveAll(sale.getItems());
}
}
And the problem is exactly how this reference is being made. In the current private Client client; way , the client object is being passed in full instead of its id, that's why it throws this following error when I try to register the sale.
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDate` from String "31/05/1968": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '31/05/1968' could not be parsed at index 0; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String "31/05/1968": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '31/05/1968' could not be parsed at index 0<EOL> at [Source: (PushbackInputStream); line: 1, column: 87] (through reference chain: MyNameIsRafaelSampaio.github.com.bruxo_vendas_ltda_api.model.Sale["client"]->MyNameIsRafaelSampaio.github.com.bruxo_vendas_ltda_api.model.Client["birthDate"])]
As was to be expected, since the column birthDate present in the client entity is not being treated correctly in the sale entity. I did research on a possible solution but none made much sense to me, I believe for being a newbie, one of the solutions that I found more understandable was the use of the #MapsId tag. I tried to make changes to adapt, but I was not successful, if you can help I will be grateful.
package com.hashedin.employeemanagementsystem.entities;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Data
#Table(name="employee")
#Entity(name="User")
public class User{
public User(){
this.individual = new Individual();
this.workExperience = null;
this.experienceInMonths = null;
this.jobRole = null;
this.primaryContact = null;
this.secondaryContact = null;
this.employeeID = null;
this.joiningDate = null;
this.employeeCategory = null;
this.exitDate = null;
this.educationDetails = null;
}
#Id
//Employee 4 digit ID
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="employee_id")
private Long empID;
//employee ID Code
#Column(name = "employee_code_id")
private String employeeID;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="first_name", column = #Column(name="employee_first_name")),
#AttributeOverride(name="last_name", column = #Column(name="employee_last_name")),
#AttributeOverride(name="email", column = #Column(name="employee_email")),
#AttributeOverride(name="phone", column = #Column(name="employee_phone")),
})
private Individual individual;
//Primary and Secondary Contacts
#Embedded
#AttributeOverrides({
#AttributeOverride(name = "email", column = #Column(name = "primary_contact_email")),
#AttributeOverride(name = "Individual.first_name", column = #Column(name = "primary_contact_first_name")),
#AttributeOverride(name = "last_name", column = #Column(name = "primary_contact_last_name")),
#AttributeOverride(name = "phone", column = #Column(name = "primary_contact_phone"))
})
private Individual primaryContact;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="email", column = #Column(name="secondary_contact_email")),
#AttributeOverride(name="first_name", column=#Column(name="secondary_contact_first_name")),
#AttributeOverride(name="last_name", column=#Column(name="secondary_contact_last_name")),
#AttributeOverride(name="phone", column=#Column(name="secondary_contact_phone"))
})
private Individual secondaryContact;
//jobRole
#Embedded
private JobRole jobRole;
//joining date and exit date (mentioned for Fixed Employees / probation period)
#Column(name="joining_date")
private Date joiningDate;
#Column(name="exit_date")
private Date exitDate;
//category, experience and highest degree
#OneToOne(cascade = CascadeType.ALL)
private Education educationDetails;
#Column(name="employee_category")
private String employeeCategory;
#Column(name="total_experience")
private Integer experienceInMonths;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name="employee_id")
private List<Employment> workExperience;
public User(String firstName, String lastName, Location location, String email, String phone, String employeeID, Individual primaryContact, Individual secondaryContact, Date joiningDate, String employeeCategory, Date exitDate, Integer experience, Education educationDetails, JobRole jobRole, List<Employment> exp) {
this.individual = new Individual(firstName, lastName, location, email, phone);
this.workExperience = exp;
this.experienceInMonths = experience;
this.jobRole = jobRole;
this.primaryContact = primaryContact;
this.secondaryContact = secondaryContact;
this.employeeID = employeeID;
this.joiningDate = joiningDate;
this.employeeCategory = employeeCategory;
this.exitDate = exitDate;
this.educationDetails = educationDetails;
}
public Individual getIndividual() {
return individual;
}
public void setIndividual(Individual individual) {
this.individual = individual;
}
public Long getEmpID() {
return empID;
}
public void setEmpID(Long empID) {
this.empID = empID;
}
public Integer getExperienceInMonths() {
return experienceInMonths;
}
public void setExperienceInMonths(Integer experienceInMonths) {
this.experienceInMonths = experienceInMonths;
}
public List<Employment> getWorkExperience() {
return workExperience;
}
public void setWorkExperience(List<Employment> workExperience) {
this.workExperience = workExperience;
}
public JobRole getJobRole() {
return jobRole;
}
public void setJobRole(JobRole jobRole) {
this.jobRole = jobRole;
}
public Education getEducationDetails() {
return educationDetails;
}
public void setEducationDetails(Education educationDetails) {
this.educationDetails = educationDetails;
}
public Integer getExperience() {
return experienceInMonths;
}
public void setExperience(Integer experience) {
this.experienceInMonths = experience;
}
public Date getExitDate() {
return exitDate;
}
public void setExitDate(Date exitDate) {
this.exitDate = exitDate;
}
public String getEmployeeCategory() {
return employeeCategory;
}
public void setEmployeeCategory(String employeeCategory) {
this.employeeCategory = employeeCategory;
}
public String getEmployeeID() {
return employeeID;
}
public void setEmployeeID(String employeeID) {
this.employeeID = employeeID;
}
public Date getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
public Individual getPrimaryContact() {
return primaryContact;
}
public void setPrimaryContact(Individual primaryContact) {
this.primaryContact = primaryContact;
}
public Individual getSecondaryContact() {
return secondaryContact;
}
public void setSecondaryContact(Individual secondaryContact) {
this.secondaryContact = secondaryContact;
}
#Override
public String toString() {
return "User{" +
"empID=" + empID +
", employeeID='" + employeeID + '\'' +
", individual=" + individual.toString() +
", primaryContact=" + primaryContact +
", secondaryContact=" + secondaryContact +
", jobRole=" + jobRole +
", joiningDate=" + joiningDate +
", exitDate=" + exitDate +
", educationDetails=" + educationDetails +
", employeeCategory='" + employeeCategory + '\'' +
", experienceInMonths=" + experienceInMonths +
", workExperience=" + workExperience +
'}';
}
}
Still getting this error, please help:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boo
t/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceU
nit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.hashedin.emplo
yeemanagementsystem.entities.User column: email (should be mapped with insert="false" update="false")
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1786) ~[spring-beans-5
.3.5.jar:5.3.5]
This is what my Individual class looks like:
package com.hashedin.employeemanagementsystem.entities;
import javax.persistence.*;
import java.lang.annotation.Target;
#Embeddable
public class Individual {
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Embedded
private Location location;
#Column(name="email")
private String email;
#Column(name="phone")
private String phone;
public Individual(){
this.firstName="";
this.lastName="";
this.location=null;
this.email=null;
this.phone=null;
}
public Individual(String firstName, String lastName, Location location, String email, String phone) {
this.firstName = firstName;
this.lastName = lastName;
this.location = location;
this.email = email;
this.phone = phone;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public String toString() {
return "Individual{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", location=" + location +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
'}';
}
}
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 2 years ago.
I am studying onetomany in hibernate I have an Instructor that has more than one course.I am using Instructor and Course class for Annotating my tables with the same names in the database.in the GetInstructorCourseDemo am trying to print the Instructor information with an associated course but inSystem.out.println("Course "+tempinstructor.getCourse()); what I see in the console is Course [MyHibernate.Course#56ccd751, MyHibernate.Course#458544e0] . it seems to me hibernate can read courses from database but it can't show it correctly otherwise have i no idea what can cause this problem
#Entity
#Table(name = "instructor")
public class Instructor {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name ="first_name" )
private String first_name;
#Column(name = "last_name")
private String last_name;
#Column(name = "email")
private String email;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "instructor_detail_id")
private instructor_detail Instructor_detail;
Instructor(){}
#OneToMany(mappedBy = "instructor",cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,
CascadeType.REFRESH})
private List<Course> course;
public Instructor(String first_name, String last_name, String email) {
this.first_name = first_name;
this.last_name = last_name;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public instructor_detail getInstructor_detail() {
return Instructor_detail;
}
public void setInstructor_detail(instructor_detail instructor_detail) {
Instructor_detail = instructor_detail;
}
public List<Course> getCourse() {
return course ;
}
public void setCourse(List<Course> course) {
this.course = course;
}
public void add(Course tempciurse){
if(course==null){
course=new ArrayList<>();
}
course.add(tempciurse);
tempciurse.setInstructor(this);
}
public class GetInstructorCourseDemo {
public static void main(String[]args) {
// create session factory
SessionFactory factory = new Configuration()
.configure("hibername.cfg.xml")
.addAnnotatedClass(Instructor.class)
.addAnnotatedClass(instructor_detail.class)
.addAnnotatedClass(Course.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
int id=2;
Instructor tempinstructor=session.get(Instructor.class,id);
System.out.println("instructor : "+tempinstructor);
System.out.println("Course "+tempinstructor.getCourse());
session.getTransaction().commit();
System.out.println("Done!");
}
finally {
factory.close();
}
}
}
#Entity
#Table(name = "course")
public class Course {
#Id#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "title")
private String title;
#ManyToOne(cascade = {CascadeType.DETACH,CascadeType.REFRESH,CascadeType.MERGE,CascadeType.PERSIST})
#JoinColumn(name = "instructor_id")
private Instructor instructor;
Course(){}
public Course(String title) {
this.title = title;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
}
It missed toString() implementation in Instructor and Course types.
As you don't override it the default one is used -->
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
NB : take care to not use course and instructor references directly in toString implementation causing a circular reference and so a StackOverflow error.
for solving this issue i have to add toString method in Course, Instructor as following
for Instructor
#Override
public String toString() {
return "Instructor{" +
"id=" + id +
", first_name='" + first_name + '\'' +
", last_name='" + last_name + '\'' +
", email='" + email + '\'' +
", Instructor_detail=" + Instructor_detail +
", course=" + course +
'}';
}
for Course
#Override
public String toString() {
return "Course{" +
"id=" + id +
", title='" + title + '\'' +
'}';
}
what was causing this confusion was that I didn't have toString method and I shouldn't have Instructor filed in my toString method
I have three entity classes, I have written the query which includes join of two tables.
Table: ExpensesCategories
#Entity
#Table(name = "ExpensesCategories")
public class ExpensesCategories {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id", unique = true)
private int categoryId;
#NotNull
private String categoryName;
#NotNull
private String categoryCodeInBankStats;
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public String getCategoryCodeInBankStats() {
return categoryCodeInBankStats;
}
public void setCategoryCodeInBankStats(String categoryCodeInBankStats) {
this.categoryCodeInBankStats = categoryCodeInBankStats;
}
}
Table: Transactions
#Entity
#Table(name = "TransactionHistory")
public class TransactionHistory {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Temporal(TemporalType.DATE)
private Date dateOfTransaction;
private String transactionType;
private String refNo;
private Date valueDate;
private double withdrawalAmount;
private double depositAmount;
private double closingBalance;
#ManyToOne
#JoinColumn(name="userDetailsId", referencedColumnName="user_id")
private UserDetails userDetails;
#ManyToOne
#JoinColumn(name="expenseCategoriesId", referencedColumnName="category_id")
private ExpensesCategories expenseCategories;
public TransactionHistory(int userId, Date dateOfTransaction, String transactionType, String refNo, Date valueDate,
double withdrawalAmount, double depositAmount, double closingBalance) {
this.dateOfTransaction = dateOfTransaction;
this.transactionType = transactionType;
this.refNo = refNo;
this.valueDate = valueDate;
this.withdrawalAmount = withdrawalAmount;
this.depositAmount = depositAmount;
this.closingBalance = closingBalance;
}
public TransactionHistory() {
}
public Date getDateOfTransaction() {
return dateOfTransaction;
}
public void setDateOfTransaction(Date date) {
this.dateOfTransaction = date;
}
public String getTransactionType() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public String getRefNo() {
return refNo;
}
public void setRefNo(String refNo) {
this.refNo = refNo;
}
public Date getValueDate() {
return valueDate;
}
public void setValueDate(Date valueDate) {
this.valueDate = valueDate;
}
public double getWithdrawalAmount() {
return withdrawalAmount;
}
public void setWithdrawalAmount(double withdrawalAmount) {
this.withdrawalAmount = withdrawalAmount;
}
public double getDepositAmount() {
return depositAmount;
}
public void setDepositAmount(double depositAmount) {
this.depositAmount = depositAmount;
}
public double getClosingBalance() {
return closingBalance;
}
public void setClosingBalance(double closingBalance) {
this.closingBalance = closingBalance;
}
public UserDetails getUserDetails() {
return userDetails;
}
public void setUserDetails(UserDetails userDetails) {
this.userDetails = userDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ExpensesCategories getExpenseCategories() {
return expenseCategories;
}
public void setExpenseCategories(ExpensesCategories expenseCategories) {
this.expenseCategories = expenseCategories;
}
}
Table: User Details
#Entity
#Table(name = "Employee")
public class UserDetails {
#Id
#Column(name = "user_id", unique = true)
private int id;
#NotNull
private String firstname;
#NotNull
private String lastname;
#Column(unique = true)
#NotNull
private String emailaddress;
#NotNull
private String role;
public UserDetails(String firstname, String lastname, String emailaddress, String role) {
this.firstname = firstname;
this.lastname = lastname;
this.emailaddress = emailaddress;
this.role = role;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public UserDetails() {
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getEmailaddress() {
return emailaddress;
}
public void setEmailaddress(String emailaddress) {
this.emailaddress = emailaddress;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
#Override
public String toString() {
return "Employee [id=" + id + ", firstname=" + firstname + ", lastname=" + lastname + ", emailaddress="
+ emailaddress + ", role=" + role + "]";
}
I have written query like this in transaction entity.
#Query( nativeQuery=true, value="SELECT a.expense_categories_id, a.Total_withdrawal_Amount, b.category_code_in_bank_stats, b.category_name FROM (SELECT expense_categories_id , SUM(withdrawal_amount) AS Total_withdrawal_Amount FROM transaction_history GROUP BY expense_categories_id) a join expenses_categories b on a.expense_categories_id = b.category_id
")
List<Object[]> getCategorizedExpenses();
My Json Response is like:
[
[
1,
21,
"UPI",
"UPI Payments"
],
[
2,
3733.59,
"POS",
"Shopping"
]
]
But i want json response with column names as well:
[
[
expense_categories_id: 1,
Total_withdrawal_Amount: 21,
category_code_in_bank_stats: "UPI",
category_name: "UPI Payments"
],
[
expense_categories_id: 2,
Total_withdrawal_Amount: 3733.59,
category_code_in_bank_stats: "POS",
category_name: "Shopping"
]
]
Please help me out..
You would need to map the results directly to a POJO class and ad some json config:
1) Define the pojo
public ResultClass implements Serializable{
#JsonProperty("expense_categories_id")
private Integer expenseCategoriesId;
...
public ResultClass(Integer expenseCategoriesId ... // rest params){
this.expenseCategoriesId = expenseCategoriesId;
...
}
}
2) Define the mapping:
#SqlResultSetMapping(
name="myMapping",
classes={
#ConstructorResult(
targetClass=ResultClass.class,
columns={
#ColumnResult(name="expenseCategoriesId"),
#ColumnResult(name="totalWithdrawalAmount")
// further mappings ...
}
)
}
)
3) Define a native query
#NamedNativeQuery(name="TransactionHistory.myQuery"
, query="SELECT new mypackage.ResultClass(a.expense_categories_id as expeneCategoriesId ... ) from ...")
4) Define this method in the CrudRepository without the #Query annotation:
public List<ResultClass> myQuery();
Teh #SqlResultSetMapping and #NamedNativeQuery would need to be defined on one of your mapped entities.
Your native query will give you an object[][] as an result. So, it actually a mxn rows.
So,
I think you should create a class names Response
public class Response{
private Long expense_categories_id;
private Double Total_withdrawal_Amount;
private String category_code_in_bank_stats;
private String category_name;
//getters and setters for all attributes
}
List<Response> fillCategorizedExpenses(){
List<Response> response_List = new ArrayList<>();
Response response = null;
Object[][] // fill each object with by accessing their index from
//this array.
for() //iterate the object array. {
response = new Response();
response.setExpense_categories_id(value); // set all attributes.
....
....
....
response_List.add(response);
}
return response_List; //this will print as you need in your project.
}
Thank You :) Hope this might help you out.
I just want to explain following scenario.
I have Registration table for employee
It has one field like BranchAddress, and I have using table Branch for that with ManyToOne mapping.
#Entity
#Table(name = "temp_reg")
public class TemporaryRegistrationDTO {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int ID;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#ManyToOne(cascade=CascadeType.ALL)
private BranchDTO companyBranch;
public BranchDTO getCompanyBranch() {
return companyBranch;
}
public void setCompanyBranch(BranchDTO companyBranch) {
this.companyBranch = companyBranch;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
#Entity
#Table(name = "company_branch")
public class BranchDTO {
#Id
#GeneratedValue ( strategy = GenerationType.AUTO)
private int branchID;
public int getBranchID() {
return branchID;
}
public void setBranchID(int branchID) {
this.branchID = branchID;
}
#ManyToOne(cascade=CascadeType.ALL)
private CountriesDTO country;
#ManyToOne(cascade=CascadeType.ALL)
private StatesDTO state;
public CountriesDTO getCountry() {
return country;
}
public void setCountry(CountriesDTO country) {
this.country = country;
}
public StatesDTO getState() {
return state;
}
public void setState(StatesDTO state) {
this.state = state;
}
}
#Entity
#Table(name = "company_countries")
public class CountriesDTO {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
private String countryCode;
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
private String countryName;
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
#Entity
#Table(name = "company_states")
public class StatesDTO {
#Id
#GeneratedValue ( strategy = GenerationType.AUTO)
private int state_id;
private String state;
private String stateCode;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getStateCode() {
return stateCode;
}
public void setStateCode(String stateCode) {
this.stateCode = stateCode;
}
#Override
public String toString() {
return "StatesDTO [statesID=" + state_id + ", state=" + state + ", stateCode=" + stateCode + "]";
}
public int getState_id() {
return state_id;
}
public void setState_id(int state_id) {
this.state_id = state_id;
}
}
Now, What I want is that, whenever their is request for registration, Firstly I am checking if Branch Address is available in the Branch table. If it contains an entry already, then it will retrieve Branch row and stooping from same data to Branch Table
Now, to check for BranchDTO, I have created method in Branch Repository class.
#Query("from BranchDTO where country = :country and state = :state")
public BranchDTO existsEntry(#org.springframework.data.repository.query.Param("country") CountriesDTO country,#org.springframework.data.repository.query.Param("state") StatesDTO state);
But It reflects me following error,
object references an unsaved transient instance - save the transient instance before flushing: com.example.demo.pojo.CountriesDTO
Thank you guys