Hibernate(4.3.7)PersistentList,不存储修改后的数据

时间:2017-01-27 22:31:00

标签: java spring hibernate

我在实体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);
        }
    }
}

1 个答案:

答案 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。