我在实体B列表中加载并实体A到一对多。 这被传递给m UI,其中可以添加/删除/修改实体列表B. 然后我回复那些实体修改在转换后没有在数据库中设置。 我想了解为什么以及我必须做些什么才能实现这一目标 (我找到的唯一后台解决方案是删除所有数据并重新创建;我不认为这是卷轴解决方案。)
以下是我的实体:
实体A
@Entity
@Table(name = "GL_RENTAL")
public class GlRental implements Serializable {
private static final long serialVersionUID = 3721662952504926000L;
@Id
@Column(name = "PK_RENTAL")
@GeneratedValue(generator = "TableGenerator")
@GenericGenerator(name = "TableGenerator", strategy = "com......TableGenerator", parameters = { @Parameter(name = "segment_value", value = "GL_RENTAL") })
private Integer pk;
@Version
@Column(name = "DATE_VERSION")
private Date version;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "PK_UT")
QuantificationRD quantification;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PK_RENTAL", nullable = false)
@OrderColumn(name = "INDEX_ORDER")
private List<GlRentalPeriod> periods = new ArrayList<>();
...
实体B
@Entity
@Table(name = "GL_RENTAL_PERIOD")
public class GlRentalPeriod implements Serializable {
private static final long serialVersionUID = -8190230568391952427L;
@Id
@Column(name = "PK_RENTAL_PERIOD")
@GeneratedValue(generator = "TableGenerator")
@GenericGenerator(name = "TableGenerator", strategy = "com......TableGenerator", parameters = { @Parameter(name = "segment_value", value = "GL_RENTAL_PERIOD") })
private Integer pk;
@Version
@Column(name = "DATE_VERSION")
private Date version;
@Column(name = "TYPE")
private String type;
@Column(name = "AMOUNT")
private Double amount;
@Column(name = "DATE_START")
private Date dateStart;
@Column(name = "DATE_END")
private Date dateEnd;
@Column(name = "FRANCHISE")
private Double franchise;
@Column(name = "FRANCHISE_TYPE")
private String franchiseType;
@Column(name = "FRANCHISE_UNIT")
private String franchiseUnit;
@Column(name = "PAID")
private Boolean paid;
....
这是服务
@Service
@Transactional
public class GlUtServiceImpl implements GlUtService {
@Autowired
ProduitService produitService;
@Autowired
ContractService contractService;
@Autowired
UtDao utDao;
@Autowired
GlUtDao glUtDao;
...
@Override
public void updateRental(ContexteService contexte, Integer pkUT, GlRentalBo rentalBo) {
UniteTraitement uniteTraitement = utDao.rechercherUT(pkUT);
QualificationUT qualif = uniteTraitement.getQualification();
Declaration declaration = qualif.getDeclaration();
Gestionnaire gestionnaire = gestionnaireDao.rechercherGestionnaire(contexte.getIdentifiantUtilisateur());
verificationHabilitationService.verifierDroitTraitement(gestionnaire, uniteTraitement);
verificationHabilitationService.verifierOuvertureUT(uniteTraitement);
GlRental rentalDto = rentalBo.getRental();
if (rentalDto.getPk() == null) {
// Attach qualification with rental
UtDao utDao = (UtDao) glUtDao;
QuantificationRD quantif = utDao.rechercherQuantificationRD(pkUT);
if (quantif == null) {
throw new ExceptionPkEntiteInconnu(UT.class, pkUT);
}
if (rentalDto.getQuantification() != null) {
throw new ExceptionConcurrenceOptimiste("Des informations de loyer existent déjà");
}
rentalDto.setQuantification(quantif);
// Save
glUtDao.createRental(rentalDto);
}
else {
GlRental rental = glUtDao.getRental(pkUt)); // error is here, this is readonly request
List<GlRentalPeriod> rentalPeriodRemovals = new ArrayList<>();
for (GlRentalPeriod rentalPeriod : rental.getPeriods()) {
GlRentalPeriod rentalPeriodToRemove = rentalPeriod;
for (GlRentalPeriod rentalPeriodDto : rentalDto.getPeriods()) {
// Period already exists in database : modify date
if (rentalPeriodDto.getPk() != null && Integer.compare(rentalPeriodDto.getPk(), rentalPeriod.getPk()) == 0) {
rentalPeriodToRemove = null;
rentalPeriod.setAmount(rentalPeriodDto.getAmount());
rentalPeriod.setDateStart(rentalPeriodDto.getDateStart());
rentalPeriod.setDateEnd(rentalPeriodDto.getDateEnd());
rentalPeriod.setFranchise(rentalPeriodDto.getFranchise());
rentalPeriod.setFranchiseType(rentalPeriodDto.getFranchiseType());
rentalPeriod.setFranchiseUnit(rentalPeriodDto.getFranchiseUnit());
rentalPeriod.setPaid(rentalPeriodDto.getPaid());
rentalPeriod.setType(rentalPeriodDto.getType());
break;
}
}
// Period not found, to remove, set it in a list of periods to remove from database
if (rentalPeriodToRemove != null) {
rentalPeriodRemovals.add(rentalPeriod);
}
}
if (CollectionUtils.isNotEmpty(rentalPeriodRemovals)) {
rental.getPeriods().removeAll(rentalPeriodRemovals);
}
// Additionnal periods
List<GlRentalPeriod> rentalPeriodAdditionnals = rentalDto.getPeriods().stream().filter(period -> period.getPk() == null)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(rentalPeriodAdditionnals)) {
rental.getPeriods().addAll(rentalPeriodAdditionnals);
}
glUtDao.updateRental(rental);
}
}
}
答案 0 :(得分:0)
解释我帮助我解决的问题是。 铅很简单。 在我的服务中,我致电
.persist()
这是一个只读方法
GlRental rental = glUtDao.getRental(pkUt));
(我很糟糕)如果以只读方式检索数据,则不会设置对实体的任何修改。 所以我只是这样做并使用这个方法
@Override
public GlRental getRental(Integer pkUt) {
Session session = sf.getCurrentSession();
Query query = session.createQuery("select rental from com.galian.claims.core.model.GlRental rental where rental.quantification.pk = :pkUt");
query.setInteger("pkUt", pkUt);
// to avoid saving any modification when transaction is closed
//The Caller can perform modification but they must no be saved
query.setReadOnly(true);
GlRental rental = (GlRental) query.uniqueResult();
return rental;
}
所以现在我只是想知道发布DTO数据,加载实体,删除,更新,修改数据或直接发布实体和&#34;合并&#34;它不必在持久化实体中传递和复制dto。