I'm trying to test how transaction works, it's a very simple example.
Entity class:
public class BettingProgram {
@Id
private int id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "date", nullable = false)
private LocalDate date;
@JsonManagedReference
@OneToMany(mappedBy = "bettingProgram", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Event> events;
}
public class Event {
@EmbeddedId
private EventId eventId;
@JsonBackReference
@ManyToOne
@MapsId("idBettingProgram")
@JoinColumn(name = "idBettingProgram")
private BettingProgram bettingProgram;
@Column(name = "type", nullable = false)
private String type;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "dateEvent", nullable = false)
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime dateEvent;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "event", cascade = CascadeType.ALL)
private List<Market> marketList;
}
public class Market {
@EmbeddedId
private MarketId marketId;
@JsonBackReference
@ManyToOne
@JoinColumns({
@JoinColumn(name = "idEvent", referencedColumnName = "idEvent"),
@JoinColumn(name = "idBettingProgram", referencedColumnName = "idBettingProgram")
})
@Valid
@MapsId("eventId")
private Event event;
@Column(name = "name", nullable = false)
private String name;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private Status status;
}
These are the functions that manage insert for each entity:
public BettingProgramDTO createBettingProgramWithManualTransaction(BettingProgramDTO bettingProgramDTO) throws CustomException {
log.info("Betting program da creare : {}", bettingProgramDTO);
BettingProgram bettingProgramCreated = methodCreaBettingPAndEvent(bettingProgramDTO);
BettingProgramDTO bettingProgramDTOCreated = bettingProgramMapper.toDTO(bettingProgramCreated);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition());
try {
List<MarketDTO> marketDTOList = methodCreaMArketSelection(bettingProgramCreated.getEvents().getFirst(), bettingProgramDTO.getEvents().getFirst().getMarketList());
bettingProgramDTOCreated.getEvents().getFirst().setMarketList(marketDTOList);
} catch (Exception e) {
log.error("{} Got an error:{}", LogUtil.errorLogString(), e.getMessage(), e);
txManager.rollback(txStatus);
}
txManager.commit();
return bettingProgramDTOCreated;
}
public BettingProgram methodCreaBettingPAndEvent(BettingProgramDTO bettingProgramDTO) throws CustomException {
Optional<BettingProgram> optBettingProgram = bettingProgramRepository.findById(bettingProgramDTO.getId());
if (optBettingProgram.isPresent()){
throw new NotValidFieldException("Betting program già esistente.");
}
BettingProgram bettingProgram = bettingProgramMapper.toEntityWithoutSon(bettingProgramDTO);
BettingProgram bettingProgramInserted = bettingProgramRepository.save(bettingProgram);
EventDTO eventDTO = bettingProgramDTO.getEvents().getFirst();
eventDTO.setIdBettingProgram(bettingProgramInserted.getId());
log.info("Event da creare : {}", eventDTO);
Event eventCreated = eventMapper.toEntityWithoutSon(eventServiceTransactional.createEventWithTransaction(eventDTO));
bettingProgramInserted.getEvents().add(eventCreated);
return bettingProgramInserted;
}
public List<MarketDTO> methodCreaMArketSelection(Event event, List<MarketDTO> marketDTO) throws CustomException {
List<MarketDTO> marketDTOList = new ArrayList<>();
for (MarketDTO marketDTOToCreate : marketDTO){
marketDTOToCreate.setIdBettingProgram(event.getEventId().getIdBettingProgram());
marketDTOToCreate.setIdEvent(event.getEventId().getIdEvent());
log.info("Market dto da creare : {}", marketDTOToCreate);
MarketDTO marketDTOCreated = marketServiceTransactional.createMarketWithTransaction(event, marketDTOToCreate);
marketDTOList.add(marketDTOCreated);
}
return marketDTOList;
}
When I save market, I have
org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was already associated with the session: [com.gestionebettingoffer.model.Event#EventId(idBettingProgram=784, idEvent=1726)].
How can I resolve this?
halfer
20.2k20 gold badges111 silver badges208 bronze badges
lang-java
Event eventCreated = eventServiceTransactional.createEventWithTransaction(eventDTO);// Do NOT call eventMapper.toEntityWithoutSon(...) againbettingProgramInserted.getEvents().add(eventCreated);