0

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
asked May 7, 2025 at 13:39
6
  • 1
    Any reason behind the common name key in all Entities? Commented May 7, 2025 at 14:45
  • Sorry but i don't understand what do you mean for "common name key". Commented May 7, 2025 at 15:11
  • @rux, Try below. Event eventCreated = eventServiceTransactional.createEventWithTransaction(eventDTO); // Do NOT call eventMapper.toEntityWithoutSon(...) again bettingProgramInserted.getEvents().add(eventCreated); Commented May 7, 2025 at 15:50
  • @rux : I am asking for this field @Column(name = "name", nullable = false) private String name; Commented May 8, 2025 at 8:29
  • @AniruddhParihar i thought code was more readable in this way Commented May 8, 2025 at 12:39

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.