Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate(4.3.7)PersistentList,不存储修改后的数据_Java_Spring_Hibernate - Fatal编程技术网

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

Java Hibernate(4.3.7)PersistentList,不存储修改后的数据,java,spring,hibernate,Java,Spring,Hibernate,我将实体A和qui A一对多地加载到实体B的列表中。 这将传递给m UI,其中可以添加/删除/修改实体B的列表。 然后,我将在事务处理后在数据库中未设置的实体修改发回。 我想了解为什么以及我必须做些什么才能实现这一目标 (我发现的唯一的后退解决方案是删除所有数据并重新创建;我不认为这是一个卷轴解决方案)。< /P> 以下是我的实体: 实体A @Entity @Table(name = "GL_RENTAL") public class GlRental implements Serializab

我将实体A和qui A一对多地加载到实体B的列表中。 这将传递给m UI,其中可以添加/删除/修改实体B的列表。 然后,我将在事务处理后在数据库中未设置的实体修改发回。 我想了解为什么以及我必须做些什么才能实现这一目标 (我发现的唯一的后退解决方案是删除所有数据并重新创建;我不认为这是一个卷轴解决方案)。< /P> 以下是我的实体:

实体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<>();
...
这是服务

@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);
        }
    }
}
@服务
@交易的
公共类GlUtServiceImpl实现GlUtService{
@自动连线
ProduitService ProduitService;
@自动连线
合同服务合同服务;
@自动连线
宇道宇道;
@自动连线
GlUtDao GlUtDao;
...
@凌驾
public void updateRental(ContexteService contexte、整数pkUT、GlRentalBo rentalBo){
unitetraitment unitetraitment=utDao.rechercherUT(pkUT);
QualificationUT qualification=uniteTraitment.getQualification();
声明=qualif.getDeclaration();
Gestionnaire Gestionnaire=gestionnaireDao.rechercherGestionnaire(contexte.getIdentificationUsilizateur());
verificationHabilitationService.VerifierDroittRaiment(gestionnaire,UnitTraitement);
verificationHabilitationService.VerifierOutertureUT(UniteTraitment);
GlRental rentalDto=rentalBo.getRental();
if(rentalDto.getPk()==null){
//将资格与租金挂钩
UtDao UtDao=(UtDao)glUtDao;
QuantificationRD quantif=utDao.rechercherQuantificationRD(pkUT);
如果(quantif==null){
抛出新的ExceptionPKENTITENNU(UT.class,pkUT);
}
if(rentalDto.getQuantification()!=null){
抛出新的例外情况ConcurrenceOptimate(“Des informations de loyer existing déjá”);
}
rentalDto.setQuantification(quantif);
//拯救
createRental(rentalDto);
}
否则{
glrent rent=glUtDao.getrent(pkUt));//此处有错误,这是只读请求
List rentalPeriodRemovals=新建ArrayList();
for(GlRentalPeriod rentalPeriod:rent.getPeriods()){
GlRentalPeriod rentalPeriod TOREMOVE=rentalPeriod;
对于(GlRentalPeriod rentalPeriodTo:rentalTo.getPeriods()){
//数据库中已存在期间:修改日期
if(rentalPeriodDto.getPk()!=null和&Integer.compare(rentalPeriodDto.getPk(),rentalPeriod.getPk())==0){
rentalPeriodToRemove=null;
setAmount(rentalPeriodTo.getAmount());
rentalPeriod.setDateStart(RentalPeriodTo.getDateStart());
rentalPeriod.setDateEnd(rentalPeriodTo.getDateEnd());
rentalPeriod.set特许经营权(rentalPeriodDto.get特许经营权());
rentalPeriod.Set特许经营类型(RentalPeriodTo.Get特许经营类型());
rentalPeriod.set特许经营单位(rentalPeriodDto.get特许经营单位());
rentalPeriod.setPaid(rentalPeriodDto.getPaid());
setType(rentalPeriodTo.getType());
打破
}
}
//找不到句点,若要删除,请在要从数据库中删除的句点列表中设置它
如果(rentalPeriodToRemove!=null){
添加(rentalPeriod);
}
}
if(收款提成不为空(租金期间移动)){
rental.getPeriods().removeAll(rentalPeriodRemovals);
}
//附加期
List RentalPeriodAdditionals=rentalDto.getPeriods().stream().filter(period->period.getPk()==null)
.collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(RentalPeriodAdditionals)){
rental.getPeriods().addAll(rentalperiodadditionals);
}
glUtDao.updateRental(租赁);
}
}
}

解释我的pb帮助我解决了问题。 Pb是简单的。 为我服务,我打电话

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;
    }
(我很糟糕)若数据检索为只读,则不会设置对实体的任何修改。 所以我就这么做,用这个方法

public GlRental getRentalByPk(Integer pkRental) {
        return (GlRental) sf.getCurrentSession().get(GlRental.class, pkRental);
    }

所以现在我只是想知道是否最好发布DTO数据、加载实体、删除、更新、修改其数据,或者直接发布实体并“合并”它,而不必在持久化实体中传递和复制DTO。

而不查看实际持久化实体的代码,可能使用EntityManager,我们看不出你做错了什么。我可能会用服务代码更新我的副本。多亏了你的问题,我找到了问题所在。它是如此的愚蠢,我没有看到它。在更新案例中,当my object Rental的PK不为空时,我加载此对象以修改中的数据列表。但是我忘记了名为returnreadonly data的方法。所以我用另一种方法修复了它,它直接通过对象的PK检索数据
public GlRental getRentalByPk(Integer pkRental) {
        return (GlRental) sf.getCurrentSession().get(GlRental.class, pkRental);
    }