英文:
How to avoid saving truncated data from JPA entity
问题
I am trying to save a bunch of data from two different entities named auditor_stamp_duty_report and deed_of_assignment. These 2 entities share a one to one and join table relationship. When I try to persist data from postman using the post method, only data from one entity gets saved into the database. The data for the other entity gets truncated.
Here is my entity classes;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@Entity
@Table(name="auditor_stamp_duty_report")
public class AuditorStampDutyReport implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "id_of_tax_payer_organization", referencedColumnName = "id")
private Organization organization;
@Column(name = "tin_of_tax_payer_organization")
private Long tin_of_tax_payer_organization;
@Column(name = "period_covered")
private String period_covered;
@Column(name = "date_of_transaction")
private LocalDate date_of_transaction;
@JoinColumn(name = "duty_payer")
private String duty_payer;
@Column(name = "tin_of_duty_payer")
private Long tin_of_duty_payer;
@Column(name = "address_of_duty_payer")
private String address_of_duty_payer;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "instrument_id", referencedColumnName = "id")
private Instruments instruments;
@Column(name = "assessment_number")
private Long assessment_number;
@Column(name = "receipt_number")
private String receipt_number;
@Column(name = "consideration")
private Double consideration;
@Column(name = "rate")
private Double rate;
@Column(name = "amount_payable")
private Double amount_payable;
@Column(name = "amount_paid")
private Double amount_paid;
@Column(name = "balance")
private Double balance;
@Column(name = "penalty")
private Double penalty;
@Column(name = "outstanding")
private Double outstanding;
@Column(name = "remarks")
private String remarks;
@Column(name="amount_recoverable")
private Double amount_recoverable;
@Column(name="date_of_payment")
private LocalDate date_of_payment;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "user_profile_id", referencedColumnName = "id")
private UserProfile userProfile;
@OneToOne
@JoinTable(
name="auditor_stamp_duty_report_deed_of_assignment",
joinColumns = @JoinColumn(name="auditor_stamp_duty_report_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name="deed_of_assignment_id", referencedColumnName = "id")
)
private DeedOfAssignment deed_of_assignment_id;
}
//second entity
package com.oasis.firsbacklogbackend.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Data
@Entity
@Table(name = "deed_of_assignment")
public class DeedOfAssignment implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@ManyToOne
@JoinColumn(name="state_id", referencedColumnName="id")
private State state;
@ManyToOne
@JoinColumn(name="lga_id", referencedColumnName = "id")
private Lga lga;
@Column(name="ward")
private Long ward;
@Column(name="description_of_location")
private String description_of_location;
}
also look at my dto layer which I am using to transfer data for both entities below:
import lombok.Data;
import java.time.LocalDate;
@Data
public class AuditorStampDutyReportDto {
private Long id;
private Long id_of_tax_payer_organization;
private String duty_payer;
private Long tin_of_tax_payer_organization;
private String period_covered;
private LocalDate date_of_transaction;
private Long tin_of_duty_payer;
private String address_of_duty_payer;
private Long instrument_id;
private Long assessment_number;
private String receipt_number;
private Double consideration;
private Double rate;
private Double amount_payable;
private Double amount_paid;
private Double balance;
private Double penalty;
private LocalDate date_of_payment;
private Double amount_recoverable;
private Double outstanding;
private String remarks;
private Long user_profile_id;
private Long deed_of_assignment_id;
private Long state_id;
private Long lga_id;
private Long ward;
private String description_of_location;
}
here is the service
@Data
@Service
public class AuditorStampDutyReportService {
private Logger logger = Logger.getLogger(AuditorStampDutyReportService.class.getName());
@Autowired
private BanksRepository banksRepository;
@Autowired
private AuditorStampDutyReportRepository auditorStampDutyReportRepository;
@Autowired
private OrganizationRepository organizationRepository;
@Autowired
private LgaRepository lgaRepository;
@Autowired
private StateRepository stateRepository;
@Autowired
private InstrumentsRepository instrumentsRepository;
@Autowired
private DeedOfAssignmentRepository deedOfAssignmentRepository;
@Autowired
private UserProfileRepository userProfileRepository;
public AuditorStampDutyReport dtoToEntity (AuditorStampDutyReportDto dto){
AuditorStampDutyReport report = new AuditorStampDutyReport();
report.setId(dto.getId());
Organization organization = organizationRepository.findById(dto.getId_of_tax_payer_organization()).orElse(null);
report.setOrganization(organization);
report.setTin_of_tax_payer_organization(dto.getTin_of_tax_payer_organization());
report.setDate_of_transaction(dto.getDate_of_transaction());
report.setPeriod_covered(dto.getPeriod_covered());
report.setDuty_payer(dto.getDuty_payer());
report.setTin_of_duty_payer(dto.getTin_of_duty_payer());
report.setAddress_of_duty_payer(dto.getAddress_of_duty_payer());
Instruments instruments = instrumentsRepository.findById(dto.getInstrument_id()).orElse(null);
report.setInstruments(instruments);
report.setAssessment_number(dto.getAssessment_number());
report.setReceipt_number(dto.getReceipt_number());
report.setConsideration(dto.getConsideration());
report.setRate(dto.getRate());
report.setAmount_payable(dto.getAmount_payable());
report.setAmount_paid(dto.getAmount_paid());
report.setBalance(dto.getBalance());
report.setPenalty(dto.getPenalty());
report.setDate_of_payment(dto.getDate_of_payment());
report.setAmount_recoverable(dto.getAmount_recoverable());
report.setOutstanding(dto.getOutstanding());
report.setRemarks(dto.getRemarks());
UserProfile userProfile = userProfileRepository.findById(dto.getUser_profile_id()).orElse(null);
report.setUserProfile(userProfile);
if(dto.getDeed_of_assignment_id()!=null && dto.getDeed_of_assignment_id() > 0) {
DeedOfAssignment deedOfAssignment = deedOfAssignmentRepository.findById(dto.getDeed_of_assignment_id()).orElse(null);
if (deedOfAssignment != null) {
report.setDeed_of_assignment_id(deedOf
<details>
<summary>英文:</summary>
I am trying to save a bunch of data from two different entities named auditor_stamp_duty_report and deed_of assignment. These 2 entities share a one to one and join table relationship. When I try to persist data from postman using the post method, only data from one entity gets saved into the database. The data for the other entity gets truncated.
Here is my entity classes;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@Entity
@Table(name="auditor_stamp_duty_report")
public class AuditorStampDutyReport implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "id_of_tax_payer_organization", referencedColumnName = "id")
private Organization organization;
@Column(name = "tin_of_tax_payer_organization")
private Long tin_of_tax_payer_organization;
@Column(name = "period_covered")
private String period_covered;
@Column(name = "date_of_transaction")
private LocalDate date_of_transaction;
@JoinColumn(name = "duty_payer")
private String duty_payer;
@Column(name = "tin_of_duty_payer")
private Long tin_of_duty_payer;
@Column(name = "address_of_duty_payer")
private String address_of_duty_payer;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "instrument_id", referencedColumnName = "id")
private Instruments instruments;
@Column(name = "assessment_number")
private Long assessment_number;
@Column(name = "receipt_number")
private String receipt_number;
@Column(name = "consideration")
private Double consideration;
@Column(name = "rate")
private Double rate;
@Column(name = "amount_payable")
private Double amount_payable;
@Column(name = "amount_paid")
private Double amount_paid;
@Column(name = "balance")
private Double balance;
@Column(name = "penalty")
private Double penalty;
@Column(name = "outstanding")
private Double outstanding;
@Column(name = "remarks")
private String remarks;
@Column(name="amount_recoverable")
private Double amount_recoverable;
@Column(name="date_of_payment")
private LocalDate date_of_payment;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "user_profile_id", referencedColumnName = "id")
private UserProfile userProfile;
@OneToOne
@JoinTable(
name="auditor_stamp_duty_report_deed_of_assignment",
joinColumns = @JoinColumn(name="auditor_stamp_duty_report_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name="deed_of_assignment_id", referencedColumnName = "id")
)
private DeedOfAssignment deed_of_assignment_id;
}
//second entity
package com.oasis.firsbacklogbackend.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Data
@Entity
@Table(name = "deed_of_assignment")
public class DeedOfAssignment implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@ManyToOne
@JoinColumn(name="state_id", referencedColumnName="id")
private State state;
@ManyToOne
@JoinColumn(name="lga_id", referencedColumnName = "id")
private Lga lga;
@Column(name="ward")
private Long ward;
@Column(name="description_of_location")
private String description_of_location;
}
also look at my dto layer which I am using to transfer data for bith entities below:
import lombok.Data;
import java.time.LocalDate;
@Data
public class AuditorStampDutyReportDto {
private Long id;
private Long id_of_tax_payer_organization;
private String duty_payer;
private Long tin_of_tax_payer_organization;
private String period_covered;
private LocalDate date_of_transaction;
private Long tin_of_duty_payer;
private String address_of_duty_payer;
private Long instrument_id;
private Long assessment_number;
private String receipt_number;
private Double consideration;
private Double rate;
private Double amount_payable;
private Double amount_paid;
private Double balance;
private Double penalty;
private LocalDate date_of_payment;
private Double amount_recoverable;
private Double outstanding;
private String remarks;
private Long user_profile_id;
private Long deed_of_assignment_id;
private Long state_id;
private Long lga_id;
private Long ward;
private String description_of_location;
}
here is the service
@Data
@Service
public class AuditorStampDutyReportService {
private Logger logger = Logger.getLogger(AuditorStampDutyReportService.class.getName());
@Autowired
private BanksRepository banksRepository;
@Autowired
private AuditorStampDutyReportRepository auditorStampDutyReportRepository;
@Autowired
private OrganizationRepository organizationRepository;
@Autowired
private LgaRepository lgaRepository;
@Autowired
private StateRepository stateRepository;
@Autowired
private InstrumentsRepository instrumentsRepository;
@Autowired
private DeedOfAssignmentRepository deedOfAssignmentRepository;
@Autowired
private UserProfileRepository userProfileRepository;
public AuditorStampDutyReport dtoToEntity (AuditorStampDutyReportDto dto){
AuditorStampDutyReport report = new AuditorStampDutyReport();
report.setId(dto.getId());
Organization organization = organizationRepository.findById(dto.getId_of_tax_payer_organization()).orElse(null);
report.setOrganization(organization);
report.setTin_of_tax_payer_organization(dto.getTin_of_tax_payer_organization());
report.setDate_of_transaction(dto.getDate_of_transaction());
report.setPeriod_covered(dto.getPeriod_covered());
report.setDuty_payer(dto.getDuty_payer());
report.setTin_of_duty_payer(dto.getTin_of_duty_payer());
report.setAddress_of_duty_payer(dto.getAddress_of_duty_payer());
Instruments instruments = instrumentsRepository.findById(dto.getInstrument_id()).orElse(null);
report.setInstruments(instruments);
report.setAssessment_number(dto.getAssessment_number());
report.setReceipt_number(dto.getReceipt_number());
report.setConsideration(dto.getConsideration());
report.setRate(dto.getRate());
report.setAmount_payable(dto.getAmount_payable());
report.setAmount_paid(dto.getAmount_paid());
report.setBalance(dto.getBalance());
report.setPenalty(dto.getPenalty());
report.setDate_of_payment(dto.getDate_of_payment());
report.setAmount_recoverable(dto.getAmount_recoverable());
report.setOutstanding(dto.getOutstanding());
report.setRemarks(dto.getRemarks());
UserProfile userProfile = userProfileRepository.findById(dto.getUser_profile_id()).orElse(null);
report.setUserProfile(userProfile);
//why is deed of assignment is not getting saved into database?
// DeedOfAssignment deedOfAssignment= null;
if(dto.getDeed_of_assignment_id()!=null && dto.getDeed_of_assignment_id() > 0) {
DeedOfAssignment deedOfAssignment = deedOfAssignmentRepository.findById(dto.getDeed_of_assignment_id()).orElse(null);
if (deedOfAssignment != null) {
report.setDeed_of_assignment_id(deedOfAssignment);
State state = stateRepository.findById(dto.getState_id()).orElse(null);
deedOfAssignment.setState(state);
Lga lga = lgaRepository.findById(dto.getLga_id()).orElse(null);
deedOfAssignment.setLga(lga);
deedOfAssignment.setWard(dto.getWard());
deedOfAssignment.setDescription_of_location(dto.getDescription_of_location());
}
}
report= auditorStampDutyReportRepository.save(report);
return report;
}
data truncation
{
//gets into the auditor_stamp_duty-report table successfully
"id_of_tax_payer_organization": 1,
"id_of_duty_payer_or_bank": 29,
"tin_of_tax_payer_organization": 3329644,
"period_covered": "July 2017 to May 2010",
"date_of_transaction": "2020-11-29",
"tin_of_duty_payer_or_bank": 382890,
"address_of_duty_payer_or_bank": "15, IBB close, Aso Drive, Fct, Abuja",
"instrument_id": 13,
"assessment_number": 219,
"receipt_number": "cc92384",
"consideration": 19470.0,
"rate": 16.0,
"amount_payable": 22000,
"amount_paid": 280000,
"balance": 2999000.0,
"penalty": 398290.0,
"outstanding": 7800.0,
"remarks": "Are no longer in operation.",
"user_profile_id": 1,
//does not get into the deed_of_assignment table successfully
"deed_of_assignment_id": 6,
"state_id": 20,
"lga_id": 230,
"ward": 12,
"description_of_location": "A brown bungalow"
}
I would appreciate your help
</details>
# 答案1
**得分**: 1
我通过按照项目要求修改了我的服务层逻辑,成功解决了问题。以下是我的服务部分的代码片段:
```java
if (instruments != null && instruments.getName().equalsIgnoreCase("Deed of Assignment")) {
DeedOfAssignment deedOfAssignment = new DeedOfAssignment();
report.setDeedOfAssignmentId(deedOfAssignment);
State state = stateRepository.findById(dto.getStateId()).orElse(null);
deedOfAssignment.setState(state);
if (state != null) {
Lga lga = lgaRepository.findById(dto.getLgaId()).orElse(null);
deedOfAssignment.setLga(lga);
}
deedOfAssignment.setWard(dto.getWard());
deedOfAssignment.setDescriptionOfLocation(dto.getDescriptionOfLocation());
}
我还在我的一对一实体映射中添加了(cascade=CascadeType.ALL),就像这样:
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(
name="auditor_stamp_duty_report_deed_of_assignment",
joinColumns = @JoinColumn(name="auditor_stamp_duty_report_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name="deed_of_assignment_id", referencedColumnName = "id")
)
private DeedOfAssignment deedOfAssignmentId;
这样做后,成功地将持久化数据保存到两个表/实体中,并且得到了所需的结果,而且不会截断数据。
英文:
I was able to fix it by modifying the logic of my service layer in line with the requirements of my project. Here is the code snippet for my service below:
if (instruments != null && instruments.getName().equalsIgnoreCase("Deed of Assignment")) {
DeedOfAssignment deedOfAssignment = new DeedOfAssignment();
report.setDeedOfAssignmentId(deedOfAssignment);
State state = stateRepository.findById(dto.getStateId()).orElse(null);
deedOfAssignment.setState(state);
if (state != null) {
Lga lga = lgaRepository.findById(dto.getLgaId()).orElse(null);
deedOfAssignment.setLga(lga);
}
deedOfAssignment.setWard(dto.getWard());
deedOfAssignment.setDescriptionOfLocation(dto.getDescriptionOfLocation());
}
I also added (cascade=CascadeType.ALL) to my oneToOne entity mapping like this:
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(
name="auditor_stamp_duty_report_deed_of_assignment",
joinColumns = @JoinColumn(name="auditor_stamp_duty_report_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name="deed_of_assignment_id", referencedColumnName = "id")
)
private DeedOfAssignment deedOfAssignmentId;
and it worked, saving the persisted data into the two tables/entities and producing the desired result without truncating the data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论