Currently I'm facing an issue when convert entities to JSON
@Entity
class EntityA {
@OneToMany(mappedBy = "parent",cascade = CascadeType.ALL)
EntityB entityB;
@OneToMany(mappedBy = "parent",cascade = CascadeType.ALL)
EntityC entityC;
}
In DB I have 100k Entities A and each entity A has around ~500 entities B/C
I need to build a service to do following
a. Convert 100k entities A to json String ( which must include data Entity B and C)
b. Save json String to a file
c. Delete 100k entities A ( also B,C)
I use JPA pagination to get 1000 entities A each time like this
interface EntityARepository extends JpaRepository<EntityA, String>, JpaSpecificationExecutor<EntityA> {
Slice<EntityA> findAll(Pageable pageable);
}
And in Service I implement like this
@Service
class EntityToJsonService {
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
@Autowired
EntityARepository entityARepository;
@Transactional
public void convertAndProcess() throws Exception {
Slice<EntityA> slice = null;
Pageable pageable = PageRequest.of(0,100);
List<String> deletedIds = new ArrayList<>();
while(true) {
slice = entityARepository.findAll(pageable);
log.info("slice ekyc info - page number {}, numberOfElements: {}, size: {}",
slice.getNumber(), slice.getNumberOfElements(), slice.getSize());
for (EntityA entityA : slice.getContent()) {
//convert to json
byte[] data = ow.writeValueAsBytes(entityA);
Files.write(Paths.get("path"), data);
deletedIds.add(e.getId());
}
if (!slice.hasNext()) {
break;
}
pageable = slice.nextPageable();
entityManager.flush();
entityManager.clear();
}
//delete data after converted
deleteEntityAAndChildrenRecords(deletedIds);
}
}
Although I do paging and load 100 entity A each time , I will get out of memory issue when running above service ( when process to page ~700).
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3664)
at java.lang.String.<init>(String.java:207)
at java.lang.StringBuilder.toString(StringBuilder.java:407)
at com.fasterxml.jackson.core.util.TextBuffer.contentsAsString(TextBuffer.java:426)
at com.fasterxml.jackson.core.io.SegmentedStringWriter.getAndClear(SegmentedStringWriter.java:83)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3410)
at com.vladmihalcea.hibernate.type.util.ObjectMapperWrapper.toString(ObjectMapperWrapper.java:58)
Does anyone got any idea to implement the service to handle this case Thanks