-1

I have entity Customer and entity Ticket.

Customer can have two different tickets. List of Tickets and OneToMany relationship is not suitable there, because I should have two different fields in Customer entity for tickets: ownTicket and refererTicket. Please help me implement this relationship. How it can be done?

Yuriy
  • 1,370
  • 4
  • 14
  • 30

3 Answers3

2

You can have two one to one relationships, like so:

class Costumer {
    @OneToOne
    Ticket ownTicket;

    @OneToOne
    Ticket refererTicket;
}

Just give different names. And then, in the Ticket class, if you do want to map both ways, I believe you have to use the mappedBy property:

class Ticket {
    @OneToOne(mappedBy="ownTicket")
    Costumer owner;

    @OneToOne(mappedBy="refererTicket")
    Costumer referer;
}

If Ticket can have only one Costumer, then this is what I would do:

Create a relationship class, called TicketCostumer or something:

class TicketCostumer {
    @OneToOne
    Ticket ticket;

    @ManyToOne
    Costumer costumer;

    Type type;
}

Where Type is an enum you create that has OWNER and REFERER;

Now each ticket can have only one of this:

class Ticket {
    @OneToOne
    CostumerTicket ct;
}

And finally, on Costumer, you can decide how to handle things; you could have a list and guarantee by hand that there is not more than one of each kind (or try to use the @UniqueBy or something like that), or you can have two separated fields to control it.

Luan Nico
  • 5,376
  • 2
  • 30
  • 60
  • But Ticket should have only one Customer field, one ticket can be mapped only to one customer, but customer can have two different tickets – Yuriy Apr 21 '17 at 17:03
  • @Yuriy I uppdated my answer considering this case. I thought one ticket could have both an owner and a referer. But it seems that it can have either but not both, so I updated. – Luan Nico Apr 21 '17 at 17:14
2

You should map it as a @OneToMany but hide this implementation detail. This could look as below: ticket has an extra column indicating its type.

@Entity
public class Customer {

    @OneToMany
    @JoinColumn(name = "customer_id")
    @MapKeyColumn(name = "ticket_type")
    @MapKeyEnumerated(EnumType.String)
    private Map<TicketType, Ticket> tickets;

    // we will not expose the tickets collection
    // the fact it is a @OneToMany is then transparent to all client code

    public Ticket getOwnTicket(){
        return tickets.get(TicketType.O);
    }

    public Ticket getReferrerTicket(){
        return tickets.get(TicketType.R); 
    }

    public void setOwnTicket(Ticket ticket){
        //ticket.setType(TicketType.O); //may not be required
        tickets.put(TicketType.O, ticket);
    }

    public void setReferrerTicket(Ticket ticket){
        //ticket.setType(TicketType.R); //may not be required
        tickets.put(TicketType.R, ticket);
    }
}
Alan Hay
  • 22,665
  • 4
  • 56
  • 110
1

What's the problem?

You can easily create Customer as:

public class Customer{
  ....
  @OneToOne
  Ticket ownTicket;

  @OneToOne
  Ticket refererTicket;
  ....
}
granmirupa
  • 2,780
  • 16
  • 27