0

I have 2 DB tables named respectivelly T_ACCOUNT and T_ACCOUNT_BENEFICIARY.

These tables have the following structure:

create table T_ACCOUNT (ID integer identity primary key, NUMBER varchar(9), NAME varchar(50) not null, CREDIT_CARD varchar(16), unique(NUMBER));

create table T_ACCOUNT_BENEFICIARY (ID integer identity primary key, ACCOUNT_ID integer, NAME varchar(50), ALLOCATION_PERCENTAGE decimal(5,2) not null, SAVINGS decimal(8,2) not null, unique(ACCOUNT_ID, NAME));

And the T_ACCOUNT table is bound to the T_ACCOUNT_BENEFICIARY table with a one to many relationship, this is the graphical representation:

enter image description here

So this is the first class named Account that map the T_ACCOUNT table:

@Entity
@Table(name="T_ACCOUNT")
public class Account {

    @Id
    @GeneratedValue
    @Column(name="id")
    private Long entityId;

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

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

    @OneToMany
    @JoinColumn(name="ACCOUNT_ID")
    private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();

    @Column(name="CREDIT_CARD")
    private String creditCardNumber;

    // GETTERS & SETTERS
}

And this is the Beneficiary class that map the T_ACCOUNT_BENEFICIARY table:

/**
 * A single beneficiary allocated to an account. Each beneficiary has a name (e.g. Annabelle) and a savings balance
 * tracking how much money has been saved for he or she to date (e.g. $1000).
 */
@Entity
@Table(name="T_ACCOUNT_BENEFICIARY")
public class Beneficiary {

    @Id
    @GeneratedValue
    @Column(name="ID")
    private Long entityId;

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

    @Embedded
    @AttributeOverride(name="value",column=@Column(name="ALLOCATION_PERCENTAGE"))
    private Percentage allocationPercentage;

    @Embedded
    @AttributeOverride(name="value",column=@Column(name="SAVINGS"))
    private MonetaryAmount savings = MonetaryAmount.zero();

As you can see into the Account I have the beneficiaries field that implement the one to may relationship

@OneToMany
@JoinColumn(name="ACCOUNT_ID")
private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();

I know that, on the DB, this relationship is implemented by the ACCOUNT_ID field of the T_ACCOUNT_BENEFICIARY table (so multiple row of the T_ACCOUNT_BENEFICIARY table can have the same value of the ACCOUNT_ID field and this means that a single row of the T_ACCOUNT table can be associated to more than one rows of T_ACCOUNT_BENEFICIARY table).

As you can see in the previous sippet there is the @JoinColumn(name="ACCOUNT_ID") annotation.

My doubt is generated by the fact that I have an ACCOUNT_ID column on my T_ACCOUNT_BENEFICIARY table, infact:

create table T_ACCOUNT_BENEFICIARY (ID integer identity primary key, ACCOUNT_ID integer, NAME varchar(50), ALLOCATION_PERCENTAGE decimal(5,2) not null, SAVINGS decimal(8,2) not null, unique(ACCOUNT_ID, NAME));

but this column seems to not be mapped on the Beneficiary that map this T_ACCOUNT_BENEFICIARY table.

So my doubts is: the @JoinColumn(name="ACCOUNT_ID") is working at relational level performing the join operation on the ACCOUNT_ID column of the table mapped by the Beneficiary entity (T_ACCOUNT_BENEFICIARY) or am I missing something? How exactly is performed this join?

If my interpretation is right can I work at entity level and say to join the beneficiaries field of my Account entity class to a new accountId field inserted into my Beneficiary entity class and mapping the ACCOUNT_ID column of the T_ACCOUNT_BENEFICIARY table?

Tnx

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • JoinColumn should be used on ManyToOne and this will be your owner side, and the inverse side will have OneToMany with mappedBy attribute. – Abdullah Shaikh Jan 07 '15 at 10:39

2 Answers2

1

It seems is a Unidirectional OneToMany relationship

In JPA 2.0 a @JoinColumn can be used on a OneToMany to define the foreign key

gtgaxiola
  • 9,241
  • 5
  • 42
  • 64
  • Ok but when I writ @JoinColumn(name="ACCOUNT_ID") the meaning is that ACCOUNT_ID is refered to the column name of the T_ACCOUNT_BENEFICIARY table and not to a field of the entity class that map this table (that can not exist)? – AndreaNobili Jan 06 '15 at 20:42
  • Yes. `ACCOUNT_ID` refers to the actual Database column on `T_ACCOUNT_BENEFICIARY`. See the example on the link where the table `Phone` has a column `OWNER_ID` and the class `Employee` uses `@JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")` for the `List phones` – gtgaxiola Jan 07 '15 at 13:39
0

I'm not sure if I understand your question. But what you have done with your @JoinColumn annotation is correct and Hibernate will execute appropriate SQL statements when you have multiple beneficiaries for your account. For example executing multiple INSERTS if you have two Beneficiaries for an Account. And yes using the @JoinColumn annotation is at the hibernate level. If you want to access an Account from a Beneficiary entity you would need to define a Bidirectional relationship in the Beneficiary class like below.

@Entity
@Table("T_ACCOUNT_BENEFICIARY")
public class Beneficiary {
 @ManyToOne(mappedBy = "beneficiaries")
 Account account;
 ...
}
stack.it
  • 1,541
  • 1
  • 9
  • 3
  • my question was another, I was asking if doing @JoinColumn(name="ACCOUNT_ID") Hibernate perform the join between the 2 tables (T_ACCOUNT and T_ACCOUNT_BENEFICIARY) using the ID column of the T_ACCOUNT table and the ACCOUNT_ID column of the T_ACCOUNT_BENEFICIARY table. Is it or is it not? – AndreaNobili Jan 06 '15 at 21:34
  • Yes it will perform the join but you also need to tell hibernate what sort of join relationship it is. And in your case it is one to many and you do it exactly like you have done in your Account class by using @OneToMany annotation. Hope it helps. Cheers. – stack.it Jan 07 '15 at 13:47