Reputation: 1
Simplified code for better understanding:
Event Entity:
@Entity
@Table(name = "event")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Event {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "event", cascade = CascadeType.ALL)
@JsonIgnore
private Set<EventSupplier> eventSupplier = new HashSet<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Event event = (Event) o;
return Objects.equals(id, event.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
Supplier Entity:
@Entity
@Table(name = "supplier")
@Getter
@Setter
public class Supplier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "supplier", cascade = CascadeType.ALL)
@JsonIgnore
private Set<EventSupplier> eventSupplier = new HashSet<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Supplier sup = (Supplier) o;
return Objects.equals(id, sup.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
EventSupplier Junction Entity:
@Entity
@Table(name = "event_supplier")
@Getter
@Setter
public class EventSupplier {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "event_id")
@JsonIgnore
private Event event;
@ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.ALL)
@JoinColumn(name = "supplier_id")
@JsonIgnore
private Supplier supplier;
@Column(name = "unit_value")
@NotNull
private BigDecimal unitValue;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EventSupplier es = (EventSupplier) o;
return Objects.equals(id, es.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
@Transactional
public Event updateEvent(EventUpdateDto dto, Long id) {
Event e = eventRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Evento não encontrado!"));
// Suppliers do Dto
Set<Supplier> suppliers = supplierRepository.findAllByIdIn(dto.suppliers().keySet());
Set<Servant> servants = servantRepository.findAllByIdIn(dto.servants());
if (suppliers.isEmpty()) {
throw new RuntimeException("O evento deve ter fornecedores ligados a ele!");
}
if (servants.isEmpty()) {
throw new RuntimeException("O evento deve ter servidores ligados a ele!");
}
e.getServants().stream()
.filter(servant -> !servants.contains(servant))
.forEach(servant -> servant.getEvents().remove(e));
e.setServants(servants);
servants.forEach(s -> s.getEvents().add(e));
// Lista de suppliers ligados ao evento
List<Supplier> supsEvent = e.getEventSupplier()
.stream()
.map(EventSupplier::getSupplier)
.collect(Collectors.toList());
//Remove suppliers existentes que não estão na lista de Suppliers do dto
for (Supplier sup : supsEvent) {
if (!suppliers.contains(sup)) {
List<EventSupplier> esDelete = e.getEventSupplier()
.stream()
.filter(es -> es.getSupplier().equals(sup))
.toList();
e.getEventSupplier().removeAll(esDelete);
sup.getEventSupplier().removeAll(esDelete);
}
}
//Adiciona suppliers caso a relação não exista
for (Supplier sup : suppliers) {
if (!e.getEventSupplier().stream().anyMatch(es -> es.getSupplier().equals(sup))) {
EventSupplier newEventSupplier = new EventSupplier();
newEventSupplier.setSupplier(sup);
newEventSupplier.setEvent(e);
e.getEventSupplier().add(newEventSupplier);
}
}
//Atualiza o preço unitário da relação existente
for (Supplier sup : suppliers) {
e.getEventSupplier().stream()
.filter(es -> es.getSupplier().equals(sup))
.findFirst()
.ifPresent(es -> es.setUnitValue(dto.suppliers().get(sup.getId())));
}
e.setTotalValue(dto.totalValue());
eventRepository.save(e);
return e;
}
I have this representation of an exotic @manyToMany relationship between Event and Supplier with an EventSupplier join table which has an extra column with the unit value of each supplier.
I'm having trouble deleting relationships between events and suppliers. When I save an event in my bank, the suppliers are saved with their unit prices. When I update an event and update the unit price of an existing supplier in the relationship, it updates smoothly. However, when I remove a relationship from a supplier with the event this does not happen, it simply does not remove it!
Upvotes: 0
Views: 40