JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-008Polymorphic many-to-one associations(@ManyToOne、@Inheritance、)

一、结构

二、代码

1.

 1 package org.jpwh.model.inheritance.associations.manytoone;
 2 
 3 import org.jpwh.model.Constants;
 4 
 5 import javax.persistence.*;
 6 import javax.validation.constraints.NotNull;
 7 
 8 // Can not be @MappedSuperclass when it's a target class in associations!
 9 @Entity
10 @Inheritance(strategy = InheritanceType.JOINED)
11 public abstract class BillingDetails {
12 
13     protected Long id;
14 
15     @NotNull
16     protected String owner;
17 
18     protected BillingDetails() {
19     }
20 
21     protected BillingDetails(String owner) {
22         this.owner = owner;
23     }
24 
25     // Use property instead of field access, so calling getId() doesn't initialize a proxy!
26     @Id
27     @GeneratedValue(generator = Constants.ID_GENERATOR)
28     public Long getId() {
29         return id;
30     }
31 
32     private void setId(Long id) {
33         this.id = id;
34     }
35 
36     public String getOwner() {
37         return owner;
38     }
39 
40     public void setOwner(String owner) {
41         this.owner = owner;
42     }
43 
44     public void pay(int amount) {
45         // NOOP
46     }
47 }

 

2.

 1 package org.jpwh.model.inheritance.associations.manytoone;
 2 
 3 import javax.persistence.Entity;
 4 import javax.validation.constraints.NotNull;
 5 
 6 @Entity
 7 public class CreditCard extends BillingDetails {
 8 
 9     @NotNull
10     protected String cardNumber;
11 
12     @NotNull
13     protected String expMonth;
14 
15     @NotNull
16     protected String expYear;
17 
18     public CreditCard() {
19         super();
20     }
21 
22     public CreditCard(String owner, String cardNumber, String expMonth, String expYear) {
23         super(owner);
24         this.cardNumber = cardNumber;
25         this.expMonth = expMonth;
26         this.expYear = expYear;
27     }
28 
29     public String getCardNumber() {
30         return cardNumber;
31     }
32 
33     public void setCardNumber(String cardNumber) {
34         this.cardNumber = cardNumber;
35     }
36 
37     public String getExpMonth() {
38         return expMonth;
39     }
40 
41     public void setExpMonth(String expMonth) {
42         this.expMonth = expMonth;
43     }
44 
45     public String getExpYear() {
46         return expYear;
47     }
48 
49     public void setExpYear(String expYear) {
50         this.expYear = expYear;
51     }
52 
53 }

 

3.

 1 package org.jpwh.model.inheritance.associations.manytoone;
 2 
 3 import javax.persistence.Entity;
 4 import javax.validation.constraints.NotNull;
 5 
 6 @Entity
 7 public class BankAccount extends BillingDetails {
 8 
 9     @NotNull
10     protected String account;
11 
12     @NotNull
13     protected String bankname;
14 
15     @NotNull
16     protected String swift;
17 
18     public BankAccount() {
19         super();
20     }
21 
22     public BankAccount(String owner, String account, String bankname, String swift) {
23         super(owner);
24         this.account = account;
25         this.bankname = bankname;
26         this.swift = swift;
27     }
28 
29     public String getAccount() {
30         return account;
31     }
32 
33     public void setAccount(String account) {
34         this.account = account;
35     }
36 
37     public String getBankname() {
38         return bankname;
39     }
40 
41     public void setBankname(String bankname) {
42         this.bankname = bankname;
43     }
44 
45     public String getSwift() {
46         return swift;
47     }
48 
49     public void setSwift(String swift) {
50         this.swift = swift;
51     }
52 }

 

4.

 1 package org.jpwh.model.inheritance.associations.manytoone;
 2 
 3 import org.jpwh.model.Constants;
 4 
 5 import javax.persistence.*;
 6 import javax.validation.constraints.NotNull;
 7 
 8 @Entity
 9 @Table(name = "USERS")
10 public class User {
11 
12     @Id
13     @GeneratedValue(generator = Constants.ID_GENERATOR)
14     protected Long id;
15 
16     @NotNull
17     protected String username;
18 
19     @ManyToOne(fetch = FetchType.LAZY)
20     protected BillingDetails defaultBilling;
21 
22     public User() {
23     }
24 
25     public User(String username) {
26         this.username = username;
27     }
28 
29     public Long getId() {
30         return id;
31     }
32 
33     public String getUsername() {
34         return username;
35     }
36 
37     public void setUsername(String username) {
38         this.username = username;
39     }
40 
41     public BillingDetails getDefaultBilling() {
42         return defaultBilling;
43     }
44 
45     public void setDefaultBilling(BillingDetails defaultBilling) {
46         this.defaultBilling = defaultBilling;
47     }
48 
49 
50     // ...
51 }

 

5.测试

  1 package org.jpwh.test.inheritance;
  2 
  3 
  4 import org.jpwh.env.JPATest;
  5 import org.jpwh.model.inheritance.associations.manytoone.BillingDetails;
  6 import org.jpwh.model.inheritance.associations.manytoone.CreditCard;
  7 import org.jpwh.model.inheritance.associations.manytoone.User;
  8 import org.testng.annotations.BeforeClass;
  9 import org.testng.annotations.Test;
 10 
 11 import javax.persistence.EntityManager;
 12 import javax.transaction.UserTransaction;
 13 
 14 import static org.testng.Assert.*;
 15 
 16 public class PolymorphicManyToOne extends JPATest {
 17 
 18     @Override
 19     public void configurePersistenceUnit() throws Exception {
 20         configurePersistenceUnit("PolymorphicManyToOnePU");
 21     }
 22 
 23     @Test
 24     public void storeAndLoadItemBids() throws Exception {
 25         UserTransaction tx = TM.getUserTransaction();
 26         try {
 27             tx.begin();
 28             EntityManager em = JPA.createEntityManager();
 29 
 30             CreditCard cc = new CreditCard(
 31                 "John Doe", "1234123412341234", "06", "2015"
 32             );
 33             User johndoe = new User("johndoe");
 34             johndoe.setDefaultBilling(cc);
 35 
 36             em.persist(cc);
 37             em.persist(johndoe);
 38 
 39             tx.commit();
 40             em.close();
 41 
 42             Long USER_ID = johndoe.getId();
 43 
 44             tx.begin();
 45             em = JPA.createEntityManager();
 46             {
 47                 User user = em.find(User.class, USER_ID);
 48 
 49                 // Invoke the pay() method on a concrete subclass of BillingDetails
 50                 user.getDefaultBilling().pay(123);
 51                 assertEquals(user.getDefaultBilling().getOwner(), "John Doe");
 52             }
 53 
 54             tx.commit();
 55             em.close();
 56 
 57             tx.begin();
 58             em = JPA.createEntityManager();
 59             {
 60                 User user = em.find(User.class, USER_ID);
 61 
 62                 BillingDetails bd = user.getDefaultBilling();
 63 
 64                 assertFalse(bd instanceof CreditCard);
 65 
 66                 // Don't do this, ClassCastException!
 67                 // CreditCard creditCard = (CreditCard) bd;
 68             }
 69             {
 70                 User user = em.find(User.class, USER_ID);
 71 
 72                 //because the  defaultBilling property is
 73                 // mapped with  FetchType.LAZY , Hibernate will proxy the association target.
 74                 BillingDetails bd = user.getDefaultBilling();
 75 
 76                 CreditCard creditCard =
 77                     em.getReference(CreditCard.class, bd.getId()); // No SELECT!
 78 
 79                 assertTrue(bd != creditCard); // Careful!
 80             }
 81             tx.commit();
 82             em.close();
 83 
 84             tx.begin();
 85             em = JPA.createEntityManager();
 86             {
 87                 User user = (User) em.createQuery(
 88                     "select u from User u " +
 89                         "left join fetch u.defaultBilling " +
 90                         "where u.id = :id")
 91                     .setParameter("id", USER_ID)
 92                     .getSingleResult();
 93 
 94                 // No proxy has been used, the BillingDetails instance has been fetched eagerly
 95                 CreditCard creditCard = (CreditCard) user.getDefaultBilling();
 96             }
 97             tx.commit();
 98             em.close();
 99 
100         } finally {
101             TM.rollback();
102         }
103     }
104 
105 }

 

posted @ 2016-04-08 15:12  shamgod  阅读(192)  评论(0编辑  收藏  举报
haha