注意:为简单起见,我更改了一些variables
名称,并删除了不必要的代码来显示我的问题。
我有两个存储库:
@Repository
public interface CFolderRepository extends CrudRepository<CFolder, Long>, QuerydslPredicateExecutor<CFolder> {}
@Repository
public interface CRepository extends JpaRepository<C, Long>, CFinder, QuerydslPredicateExecutor<C> {}
类C
是:
@FilterDef(name = "INS_COMPANY_FILTER", parameters = {@ParamDef(name = "insCompanies", type = "string")})
@Filter(name = "INS_COMPANY_FILTER", condition = " INS_COMPANY in (:insCompanies) ")
@NoArgsConstructor
@AllArgsConstructor
@Audited
@AuditOverrides({@AuditOverride(forClass = EntityLog.class),
@AuditOverride(forClass = MultitenantEntityBase.class)})
@Entity
@Table(name = "INS_C")
@Getter
public class C extends MultitenantEntityBase {
@OneToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "C_FOLDER_ID")
private CFolder cFolder;
public void addFolder(List<String> clsUrl){
this.cFolder = CFolder.createFolder(clsUrl);
}
}
CFolder
是:
@Getter
@NoArgsConstructor
@Audited
@AuditOverride(forClass = EntityLog.class)
@Entity
@Table(name = "C_FOLDER")
@AllArgsConstructor
public class CFolder extends EntityBase {
@Column(name = "CREATION_FOLDER_DATE_TIME", nullable = false)
private LocalDateTime creationFolderDateTime;
@Column(name = "UPDATED_FOLDER_DATE_TIME")
private LocalDateTime updatedFolderDateTime;
@Column(name = "FOLDER_CREATED_BY", nullable = false)
private String folderCreatedBy;
@Column(name = "FOLDER_UPDATED_BY")
private String folderUpdatedBy;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "cFolder", fetch = FetchType.EAGER)
@NotAudited
private Set<FolderDocument> folderDocuments = new HashSet<>();
public static CFolder createFolder(List<String> clsUrl){
CFolder cFolder = new CFolder(LocalDateTime.now(), null, SecurityHelper.getUsernameOfAuthenticatedUser(), null, new HashSet<>());
createFolderDocuments(clsUrl, cFolder);
return cFolder;
}
public void updateFolder(List<String> clsUrl){
this.updatedFolderDateTime = LocalDateTime.now();
this.folderUpdatedBy = SecurityHelper.getUsernameOfAuthenticatedUser();
this.folderDocuments.clear();
createFolderDocuments(clsUrl, this);
}
private static void createFolderDocuments(List<String> clsUrl, CFolder cFolder) {
int documentNumber = 0;
for (String url : clsUrl) {
documentNumber++;
cFolder.folderDocuments.add(new FolderDocument(cFolder, documentNumber, url));
}
}
}
FolderDocument
是:
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Audited
@AuditOverride(forClass = EntityLog.class)
@Entity
@Table(name = "FOLDER_DOCUMENT")
public class FolderDocument extends EntityBase {
@ManyToOne
@JoinColumn(name = "C_FOLDER_ID", nullable = false)
private CFolder cFolder;
@Column(name = "DOCUMENT_NUMBER", nullable = false)
private int documentNumber;
@Column(name = "URL", nullable = false)
private String url;
}
最后我们有一个service
,我在其中使用这些entities
并尝试将它们保存到数据库或从数据库中加载:
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class CFolderService {
private final CRepository cRepository;
private final CommunicationClServiceClient communicationServiceClient;
private final CFolderRepository cFolderRepository;
public List<ClDocumentDto> getClCaseFolder(Long cId) {
C insCase = cRepository.findCById(cId);
List<ClDocumentDto> clDocumentsDto = getClDocuments(insCase.getCNumber()); // here, the object has one cFolder, but many FolderDocument inside of it
return clDocumentsDto;
}
@Transactional
public void updateCFolder(Long cId) {
C insC = cRepository.findCById(cId);
List<ClDocumentDto> clDocumentsDto = getClDocuments(insC.getCNumber());
List<String> clsUrl = clDocumentsDto.stream().filter(c -> "ACTIVE".equals(c.getCommunicationStatus())).map(ClDocumentDto::getUrl).collect(Collectors.toList());
if (Objects.isNull(insC.getCFolder())) {
insC.addFolder(clsUrl);
} else {
insC.getCFolder().updateFolder(clsUrl);
}
cFolderRepository.save(insC.getCFolder()); // here it saves additional FolderDocument instead of updateing it
cRepository.save(insC); // need second save, so can get these collection in getClaimCaseFolder successfully
}
}
我里面有两个问题。在该示例中,我试图清除从数据库中找到的对象并创建新对象。
1)
首先,我必须执行两次save
操作才能成功地以getClCaseFolder
方法(在事务性之外)还原对象。
2)
其次,每次保存时,我都会在FolderDocument
对象内将其他CFolder
对象固定到C
对象。我想清除此收藏集并保存新的收藏集。
我不确定hibernate
为什么不更新该对象?
编辑:
我认为我确实喜欢:
cRepository.save(insC);
代替this.folderDocuments.clear();
我可以做到:
for(Iterator<FolderDocument> featureIterator = this.folderDocuments.iterator();
featureIterator.hasNext(); ) {
FolderDocument feature = featureIterator .next();
feature.setCFolder(null);
featureIterator.remove();
}
但是我拿到eager
,为什么懒惰不起作用?使用它时出错。
答案 0 :(得分:0)
检查是否在ID
中设置了Entity
。
如果ID
中有entity
,并且该ID在数据库表中也存在,则休眠将更新该记录;但是,如果在实体对象中没有ID /存在ID, Hibernate始终将该对象视为新记录,并将新记录添加到表中,而不是更新。