public void /*test*/ LoadUserWithBillingDetails() {
    System.out.println("******************** testLoadUserWithBillingDetails ********************");
    UserDAO userDAO = new UserDAO();
    User user = userDAO.loadUserById(1l, false);

    Set<BillingDetails> billingDetails = user.getBillingDetails();
    Iterator<BillingDetails> billingIterator = billingDetails.iterator();

    while (billingIterator.hasNext()) {
      BillingDetails details = billingIterator.next();
      if (details instanceof BankAccount) {
        BankAccount account = (BankAccount) details;
        assertEquals("FooBar Rich Bank", account.getBankName());
        assertEquals("234234234234", account.getNumber());
      }

      if (details instanceof CreditCard) {
        CreditCard cc = (CreditCard) details;
        assertEquals("1234567890", cc.getNumber());
      }

      if (details instanceof HibernateProxy) {
        HibernateProxy proxy = (HibernateProxy) details;
        Object proxyImpl = proxy.getHibernateLazyInitializer().getImplementation();
        if (proxyImpl instanceof CreditCard) {
          CreditCard cc = (CreditCard) proxyImpl;
          assertEquals("1234567890", cc.getNumber());
        } else {
          fail("Proxy is not a CreditCard");
        }
      }
    }

    BillingDetails defaultBillingDetails = user.getDefaultBillingDetails();
    if (defaultBillingDetails instanceof HibernateProxy) {
      HibernateProxy proxy = (HibernateProxy) defaultBillingDetails;
      Object proxyImpl = proxy.getHibernateLazyInitializer().getImplementation();
      if (proxyImpl instanceof CreditCard) {
        CreditCard cc = (CreditCard) proxyImpl;
        assertEquals("1234567890", cc.getNumber());
      } else {
        fail("Proxy is not a CreditCard");
      }
    } else {
      fail("DefaultBillingDetails is not a proxy");
    }

    // HibernateUtil.closeSession();
    BillingDetailsDAO billingDetailsDAO = new BillingDetailsDAO();
    BillingDetails billingDetails1 = billingDetailsDAO.getBillingDetailsById(1l, false);
    assertNotNull(billingDetails1);
    assertTrue(billingDetails1.getUser() == user);

    user.removeBillingDetails(billingDetails1);
    HibernateUtil.getSession().flush();

    // BillingDetails billingDetails2 = billingDetailsDAO.loadBillingDetailsById(1l, false);
    BillingDetails billingDetails2 = billingDetailsDAO.getBillingDetailsById(1l, false);
    assertNull(billingDetails2);
  }
  public void /*test*/ UserItemsInitialization() throws Exception {
    System.out.println("******************** testUserItemsInitialization ********************");
    UserDAO userDAO = new UserDAO();
    User user = userDAO.getUserById(1l, false);

    assertFalse(Hibernate.isInitialized(user.getItems()));
    Set<Item> items = user.getItems();
    assertFalse(Hibernate.isInitialized(items));

    Item item = (Item) items.toArray()[0];
    assertTrue(Hibernate.isInitialized(items));
    assertNotNull(item.getName());

    User user2 = userDAO.getUserById(1l, false);
    assertTrue(user == user2);

    userDAO.evict(user);

    User user3 = userDAO.getUserById(1l, false);
    assertFalse(user == user3);

    items = user3.getItems();
    assertFalse(Hibernate.isInitialized(items));
    Hibernate.initialize(items);
    assertTrue(Hibernate.isInitialized(items));
  }
  /**
   * fetch=”join” or @Fetch(FetchMode.JOIN). The “join” fetching strategy will disabled the lazy
   * loading of all it’s related collections. Let see the example.
   */
  public void /*test*/ UserFetchingStrategies() {
    System.out.println("******************** testUserFetchingStrategies *******************");
    UserDAO userDAO = new UserDAO();
    User user = userDAO.loadUserById(1l, false);

    for (Iterator iter = user.getItems().iterator(); iter.hasNext(); ) {
      Item item = (Item) iter.next();
      assertNotNull(item.getId());
      assertNotNull(item.getName());
    }
  }
  /**
   * With save-update cascade. The cascade=”save-update” is declared in ‘BillingDetails’ to enable
   * the save-update cascade effect..
   */
  public void /*test*/ BillingDetailsCascadeSaveUpdate() {
    User u1 = new User("Christian", "Bauer", "turin", "abc123", "*****@*****.**");
    u1.setAddress(new Address("Foo", "12345", "Bar"));
    u1.setAdmin(true);

    BillingDetails ccOne =
        new CreditCard(
            "Christian  Bauer", u1, "1234567890", CreditCardType.MASTERCARD, "10", "2005");
    u1.addBillingDetails(ccOne);

    HibernateUtil.getSession().save(u1);
  }
  /**
   * With delete-orphan cascade. The cascade=”delete-orphan” is declared in ‘billingDetails’ to
   * enable the delete orphan cascade effect. When you save or update the User, it will remove those
   * ‘billingDetails’ which already mark as removed.
   *
   * <p>In short, delete-orphan allow parent table to delete few records (delete orphan) in its
   * child table.
   */
  public void /*test*/ BillingDetailsWithDeleteOrphanCascade() throws Exception {
    LogHelper.disableLogging();
    User u1 = new User("Christian", "Bauer", "turin", "abc123", "*****@*****.**");
    u1.setAddress(new Address("Foo", "12345", "Bar"));
    u1.setAdmin(true);

    HibernateUtil.getSession().save(u1);

    BillingDetails ccOne =
        new CreditCard(
            "Christian  Bauer", u1, "1234567890", CreditCardType.MASTERCARD, "10", "2005");
    u1.addBillingDetails(ccOne);

    HibernateUtil.getSession().save(ccOne);

    HibernateUtil.getSession().flush();

    UserDAO userDAO = new UserDAO();
    User user = userDAO.loadUserById(1l, false);

    Set details = user.getBillingDetails();

    for (Object detail : details) {
      LogHelper.setLogging("org.hibernate.SQL", Level.DEBUG);

      user.getBillingDetails().remove(detail);
      user.setDefaultBillingDetails(null);

      LogHelper.disableLogging();
    }

    LogHelper.setLogging("org.hibernate.SQL", Level.DEBUG);
    HibernateUtil.getSession().saveOrUpdate(u1);
    HibernateUtil.getSession().flush();
  }
  /**
   * fetch=”subselect” or @Fetch(FetchMode.SUBSELECT).
   *
   * <p>This fetching strategy is enable all its related collection in a sub select statement. Let
   * see the same query again.
   *
   * <p>With “subselect” enabled, it will create two select statements.
   *
   * <p>1. Select statement to retrieve all the Stock records.
   *
   * <p>2. Select all its related collections in a sub select query.
   */
  @org.junit.Test
  public void /*test*/ UserBatchItems() {
    System.out.println("******************* testUserBatchItems ********************");
    Session session = HibernateUtil.getSession();
    List<User> list = session.createQuery("from User").list();

    for (User user : list) {
      Set items = user.getItems();

      for (Iterator iter = items.iterator(); iter.hasNext(); ) {
        Item item = (Item) iter.next();
        assertNotNull(item.getId());
        assertNotNull(item.getName());
      }
    }
  }
  public void /*test*/ UserWithItems() throws Exception {
    System.out.println("******************** testUserWithItems ********************");

    UserDAO userDAO = new UserDAO();
    assertTrue(userDAO.findAll().size() > 0);

    User user = new User();
    user.setFirstname("Christian");
    user.setAdmin(true);
    user.clearCreatedDate();

    Collection users = userDAO.findByExample(user);

    assertNotNull(users);
    Object[] userArr = users.toArray();
    assertTrue(userArr.length > 0);
    assertTrue(userArr[0] instanceof User);

    User christian = (User) userArr[0];
    assertNotNull(christian.getId());

    Set items = christian.getItems();
    Item item = (Item) items.toArray()[0];
    assertNotNull(item.getId());

    Calendar inThreeDays = GregorianCalendar.getInstance();
    inThreeDays.roll(Calendar.DAY_OF_YEAR, 3);
    Item newItem =
        new Item(
            "Item One",
            "An item in the carsLuxury category.",
            christian,
            new MonetaryAmount(new BigDecimal("1.99"), Currency.getInstance(Locale.US)),
            new MonetaryAmount(new BigDecimal("50.33"), Currency.getInstance(Locale.US)),
            new Date(),
            inThreeDays.getTime());

    christian.addItem(newItem);

    ItemDAO itemDAO = new ItemDAO();
    itemDAO.makePersistent(newItem);

    HibernateUtil.commitTransaction();
  }