package org.dddlib.organisation.domain; import org.dayatang.domain.AbstractEntity; import org.dayatang.utils.DateUtils; import org.dddlib.organisation.domain.events.PartyTerminatedEvent; import javax.persistence.*; import java.util.Date; import java.util.List; @Entity @Table(name = "accountabilities") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "CATEGORY", discriminatorType = DiscriminatorType.STRING) @NamedNativeQueries({ @NamedNativeQuery(name = "Accountability.findAccountabilitiesByParty", query = "select o from Accountability o where (o.commissioner = :party or o.responsible = :party) and o.fromDate <= :date and o.toDate > :date")}) public abstract class Accountability<C extends Party, R extends Party> extends AbstractEntity { private static final long serialVersionUID = 3456398163374995470L; @ManyToOne(targetEntity = Party.class, cascade = CascadeType.ALL) @JoinColumn(name = "commissioner_id") private C commissioner; @ManyToOne(targetEntity = Party.class, cascade = CascadeType.ALL) @JoinColumn(name = "responsible_id") private R responsible; @Temporal(TemporalType.DATE) @Column(name = "from_date") private Date fromDate; @Temporal(TemporalType.DATE) @Column(name = "to_date") private Date toDate; protected Accountability() { } public Accountability(C commissioner, R responsible, Date fromDate) { this.commissioner = commissioner; this.responsible = responsible; this.fromDate = new Date(fromDate.getTime()); this.toDate = DateUtils.MAX_DATE; } public C getCommissioner() { return commissioner; } public void setCommissioner(C commissioner) { this.commissioner = commissioner; } public R getResponsible() { return responsible; } public void setResponsible(R responsible) { this.responsible = responsible; } public Date getFromDate() { return new Date(fromDate.getTime()); } void setFromDate(Date fromDate) { this.fromDate = fromDate; } public Date getToDate() { return toDate; } void setToDate(Date toDate) { this.toDate = toDate; } @Override public String[] businessKeys() { return new String[]{"commissioner", "responsible", "fromDate", "toDate"}; } public void terminate(Date date) { this.toDate = date; save(); } @SuppressWarnings("rawtypes") public static <T extends Accountability> List<T> findAccountabilities(Class<T> accountabilityClass, Date date) { return getRepository().createCriteriaQuery(accountabilityClass).le("fromDate", date).gt("toDate", date).list(); } @SuppressWarnings("rawtypes") static List<Accountability> findAccountabilitiesByParty(Party party, Date date) { return getRepository().createNamedQuery("Accountability.findAccountabilitiesByParty") .addParameter("party", party).addParameter("date", date).list(); } public static void when(PartyTerminatedEvent event) { Party party = getRepository().get(Party.class, event.getPartyId()); for (Accountability each : findAccountabilitiesByParty(party, event.occurredOn())) { each.terminate(event.occurredOn()); } } }