0

I am new to JPA and doing a small sample to learn about it. But I got one problem below, please help me out, and please explain why:

I have class Customer.java, which is mapped to table customer in db:

@Entity
public class Customer implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id_customer")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    // accountNumber field maps with accountNumber column in Account table
    @Column(name = "loginId", unique = true)
    private String loginId;

    @Column(name = "password")
    private String password;

    @Column(name = "firstName")
    private String firstName;

    @Column(name = "lastName")
    private String lastName;

    @Column(name = "address")
    private String address;

    @Column(name = "email")
    private String email;

    @Column(name = "phone")
    private String phone;

    @OneToMany(mappedBy="customer")
    private List<Account> accountList;

    @OneToMany(mappedBy="customer")
    private List<Card> cardList;
// getters and setters goes here
}

The above class has two lists, accountList and cardList, their generic Class (Card and Account) extends BaseInfo using Single table Inheritance.
Here is my BaseInfo.java:

@Entity
@Table(name = "account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
public class BaseInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "number")
    private String number;

    @Column(name = "availableNumber")
    private Long availableNumber;
//getter and setter here
}

Class Card.java:

@Entity
@Table(name = "account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue(value = "C")
public class Card extends BaseInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "cardType")
    private String cardType;

    @ManyToOne
    @JoinColumn(name = "id_customer")
    private Customer customer;

//getter and setter
}

And class Account.java:

@Entity
@Table(name = "account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue(value = "A")
public class Account extends BaseInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    @Column(name = "accountName")
    private String accountName;

    @Column(name = "accountType")
    private String accountType;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "dt_created")
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "dt_lst_updt")
    private Date lastUpdatedDate;

    @ManyToOne
    @JoinColumn(name = "id_customer")
    private Customer customer;

//getter, setter
}

Then, I do a query that query customer from database with loginid and password, like this:

entityTransaction.begin();

TypedQuery<Customer> query = entityManager.createQuery(
                    "SELECT c FROM " + Customer.class.getName()
                            + " c Where c.loginId= :loginId", Customer.class);
query.setParameter("loginId", loginId);

res = query.getSingleResult();

entityTransaction.commit();

The code run with no error, but the result is somethings strange to me: When I debug (or print out the result to jsp), accountList or cardList contains all Account of that customer, just like they don't care about the 'discriminator' column.

I have 2 questions:

  1. How can I archive the goal that listCard contains only Card (discrimination = c) and listAccount contains only Account (discriminator = a) ?

  2. Is there an alternative way to query listCard or listAccount without query the customer first (like I use) ??

Thank in advance! :D

user2758327
  • 41
  • 1
  • 1
  • 4
  • Can you clarify, what do you mean by `accountList and cardList contain all data of Card and Account of that customer, just like they don't care about the 'discriminator' column`? `listCard` is a list of `Card` entities, I don't know how can it contain `Account` instances, if that's what you are saying? – Predrag Maric Jan 22 '15 at 14:58
  • At Q1: it should work already. What implementation/version of JPA do you use? At Q2.Yes, e.g with this query: `SELECT Account a WHERE a.customer=:customer` – V G Jan 22 '15 at 14:58
  • pass an customer as parameter for the query? – user2758327 Jan 22 '15 at 15:29
  • Q2. Use loginId instead: `SELECT Account a WHERE a.customer.loginId = :loginId` – wypieprz Jan 22 '15 at 20:30

1 Answers1

0

I'm not sure if it's a JPA restriction or a Hibernate-specific restriction, but you may not use the same column to map two different associations.

You should use something like car_customer_id to map the association between customer and cards, and account_customer_id to map the association between customer and accounts.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255