Skip to content

Hibernate (конфигурация spring)

Синопсис

В этом посте создадим простое приложение подобное тому, которое было в двух предыдущих постах Hibernate (конфигурация в стиле xml) и Hibernate (конфигурация в стиле аннотации), только теперь хибернейт конфигурироваться будет спрингом. В этом случае у нас сразу уйдут два класса, это HibernateUtil.java так как теперь хибернейтовская сессия будет подниматься спрингом, и фэктори класс Factory.java, так как все dao-классы у нас становятся бинами и, соответственно, мэнэджеться будут спрингом. Описывать проект я здесь не буду, он такой же как в посте Работа с базой данных через JDBC

Проект можно взять с гитхаба: https://github.com/dev-blogs/spring-hibernate

Похожие посты

  • Работа с базой данных через JDBC
  • Hibernate (конфигурация в стиле xml)
  • Hibernate (конфигурация в стиле аннотации)
  • Основы JPA
  • JPA и Spring
  • Аудит и отслеживание версий для сущностных классов в Spring
  • Простой Spring MVC
  • Структура проекта

    spring-hibernate
        ├──src
        │   ├─main
        │   │   └─java
        │   │       └─com
        │   │           └─devblogs
        │   │               ├─dao
        │   │               │   ├─ItemDao.java
        │   │               │   ├─ProviderDao.java
        │   │               │   ├─WarehouseDao.java
        │   │               │   └─impl
        │   │               │       ├─ItemDaoImpl.java
        │   │               │       ├─ProviderDaoImpl.java
        │   │               │       └─WarehouseDaoImpl.java
        │   │               └─model
        │   │                   ├─Item.java
        │   │                   ├─Provider.java
        │   │                   └─Warehouse.java
        │   ├─resources
        │   │   ├─context.xml
        │   │   └─scripts
        │   │       ├─create-data-model.sql
        │   │       └─fill-database.sql
        │   └─test
        │       └─java
        │           └─com
        │               └─devblogs
        │                   └─test
        │                       ├─TestItem.java
        │                       ├─TestProvider.java
        │                       └─TestWarehouse.java
        └──pom.xml     
    

    DB скрипты

    Скрипты create-data-model.sql и fill-database.sql можно взять в посте Работа с базой данных через JDBC
    Так как в этом посте будет встроенная база данных H2, то из тех скриптов нужно будет выкинуть строчки:

    CREATE DATABASE warehouse CHARACTER SET utf8;
    USE warehouse;
    

    из скрипта create-data-model.sql и строчку:

    USE warehouse;
    

    из скрипта fill-database.sql

    Доменные классы

    Item.java

    package com.devblogs.model;
    
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "items")
    public class Item {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
         
        @Column(name = "name")
        private String name;
         
        @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
        @JoinTable(name = "items_providers",
                    joinColumns={@JoinColumn(name = "item_id")},
                    inverseJoinColumns={@JoinColumn(name = "provider_id")})
        private Set<Provider> providers = new HashSet<Provider>();
         
        @ManyToOne
        @JoinColumn(name = "warehouse_id")
        private Warehouse warehouse;
         
        public Item() {
        }
     
        public Long getId() {
            return id;
        }
     
        public void setId(Long id) {
            this.id = id;
        }
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public Set<Provider> getProviders() {
            return providers;
        }
     
        public void setProviders(Set<Provider> providers) {
            this.providers = providers;
        }
     
        public Warehouse getWarehouse() {
            return warehouse;
        }
     
        public void setWarehouse(Warehouse warehouse) {
            this.warehouse = warehouse;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            Item that = (Item) obj;
            if (!name.equals(that.name)) return false;
             
            return true;
        }
        
        @Override
        public String toString() {
        	return "[id=" + this.id + ", name=" + this.name + "]";
        }
    }
    

    Provider.java

    package com.devblogs.model;
    
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
     
    @Entity
    @Table(name = "providers")
    public class Provider {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
        @Column(name = "name")
        private String name;
        @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
        @JoinTable(name = "items_providers",
                joinColumns={@JoinColumn(name = "provider_id")},
                inverseJoinColumns={@JoinColumn(name = "item_id")})
        private Set<Item> items = new HashSet<Item>();
         
        public Provider() {    
        }
     
        public Long getId() {
            return id;
        }
     
        public void setId(Long id) {
            this.id = id;
        }
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public Set<Item> getItems() {
            return items;
        }
     
        public void setItems(Set<Item> items) {
            this.items = items;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            Provider that = (Provider) obj;
            if (!name.equals(that.name)) return false;
            return true;
        }
        
        @Override
        public String toString() {
        	return "[id=" + this.id + ", name=" + this.name + "]";
        }
    }
    

    Warehouse.java

    package com.devblogs.model;
    
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "warehouses")
    public class Warehouse {
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	@Column(name = "id")
    	private Long id;
    	@Column(name = "address")
    	private String address;
    	@OneToMany(fetch = FetchType.LAZY, mappedBy = "warehouse")
    	private Set<Item> items = new HashSet<Item>();
    
    	public Warehouse() {
    	}
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    	public String getAddress() {
    		return address;
    	}
    
    	public void setAddress(String address) {
    		this.address = address;
    	}
    
    	public Set<Item> getItems() {
    		return items;
    	}
    
    	public void setItems(Set<Item> items) {
    		this.items = items;
    	}
    	
    	@Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null || getClass() != obj.getClass()) return false;
            Warehouse that = (Warehouse) obj;
            if (!address.equals(that.address)) return false;
            return true;
        }
    	
    	@Override
    	public String toString() {
        	return "[id=" + this.id + ", address=" + this.address + "]";
        }
    }
    

    DAO слой

    ItemDao.java

    package com.devblogs.dao;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import com.devblogs.model.Item;
    
    public interface ItemDao {
    	public Item addItem(Item item) throws SQLException, Exception;
        public void updateItem(Item item) throws SQLException, Exception;
        public Item getItemById(Long id) throws SQLException, Exception;
        public Collection<Item> getAllItems() throws SQLException, Exception;
        public void deleteItem(Item item) throws SQLException, Exception;
    }
    

    ProviderDao.java

    package com.devblogs.dao;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import com.devblogs.model.Provider;
    
    public interface ProviderDao {
    	public Provider addProvider(Provider provider) throws SQLException, Exception;
        public void updateProvider(Provider provider) throws SQLException, Exception;
        public Provider getProviderById(Long id) throws SQLException, Exception;
        public Collection<Provider> getAllProviders() throws SQLException, Exception;
        public void deleteProvider(Provider provider) throws SQLException, Exception;
    }
    

    WarehouseDao.java

    package com.devblogs.dao;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import com.devblogs.model.Warehouse;
    
    public interface WarehouseDao {
    	public Warehouse addWarehouse(Warehouse warehouse) throws SQLException, Exception;
        public void updateWarehouse(Warehouse warehouse) throws SQLException, Exception;
        public Warehouse getWarehouseById(Long id) throws SQLException, Exception;
        public Collection<Warehouse> getAllWarehouses() throws SQLException, Exception;
        public void deleteWarehouse(Warehouse warehouse) throws SQLException, Exception;
    }
    

    В реализации dao-слоя обратим внимание на методы addItem, addProvider и addWarehouse на то как происходит извлечение ключа, сгенерированного базой данных. Когда мы работаем с базой данных через JDBC, для того, чтобы извлечь ключ, нам нужно создать объект KeyHolder и передать его вместе с запросом, а потом, после выполнения вставки, извлечь из него ключ. Фреймворк хибернейт сам извлечет сгенерированный ключ и просетит его в объект предметной области, поэтому нам все что надо сделать это после оператора вставки save передать объект предметной области обратной вызывающему методу.

    ItemDaoImpl.java

    package com.devblogs.dao.impl;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    import com.devblogs.dao.ItemDao;
    import com.devblogs.model.Item;
    
    @Component
    public class ItemDaoImpl implements ItemDao {
    	@Autowired
    	private SessionFactory sessionFactory;
    
    	@Transactional(readOnly = false)
    	public Item addItem(Item item) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().save(item);
    		return item;
    	}
    
    	@Transactional(readOnly = false)
    	public void updateItem(Item item) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().update(item);
    	}
    
    	@Transactional(readOnly = true)
    	public Item getItemById(Long id) throws SQLException, Exception {
    		return (Item) sessionFactory.getCurrentSession().createQuery("from Item where id = " + id).uniqueResult();
    	}
    
    	@Transactional(readOnly = true)
    	public Collection<Item> getAllItems() throws SQLException, Exception {		
    		return sessionFactory.getCurrentSession().createQuery("from Item i").list();
    	}
    
    	@Transactional(readOnly = false)
    	public void deleteItem(Item item) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().delete(item);
    	}
    }
    

    ProviderDaoImpl.java

    package com.devblogs.dao.impl;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    import com.devblogs.dao.ProviderDao;
    import com.devblogs.model.Provider;
    
    @Component
    public class ProviderDaoImpl implements ProviderDao {
    	@Autowired
    	private SessionFactory sessionFactory;
    
    	@Transactional(readOnly = false)
    	public Provider addProvider(Provider provider) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().save(provider);
    		return provider;
    	}
    
    	@Transactional(readOnly = false)
    	public void updateProvider(Provider provider) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().update(provider);
    	}
    
    	@Transactional(readOnly = true)
    	public Provider getProviderById(Long id) throws SQLException, Exception {
    		return (Provider) sessionFactory.getCurrentSession().createQuery("from Provider where id = " + id).uniqueResult();
    	}
    
    	@Transactional(readOnly = true)
    	public Collection<Provider> getAllProviders() throws SQLException, Exception {
    		return sessionFactory.getCurrentSession().createQuery("from Provider p").list();
    	}
    
    	@Transactional(readOnly = false)
    	public void deleteProvider(Provider provider) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().delete(provider);
    	}
    }
    

    WarehouseDaoImpl.java

    package com.devblogs.dao.impl;
    
    import java.sql.SQLException;
    import java.util.Collection;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    import com.devblogs.dao.WarehouseDao;
    import com.devblogs.model.Warehouse;
    
    @Component
    public class WarehouseDaoImpl implements WarehouseDao {
    	@Autowired
    	private SessionFactory sessionFactory;
    
    	@Transactional(readOnly = false)
    	public Warehouse addWarehouse(Warehouse warehouse) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().save(warehouse);
    		return warehouse;
    	}
    
    	@Transactional(readOnly = false)
    	public void updateWarehouse(Warehouse warehouse) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().update(warehouse);
    	}
    
    	@Transactional(readOnly = true)
    	public Warehouse getWarehouseById(Long id) throws SQLException, Exception {
    		return (Warehouse) sessionFactory.getCurrentSession().createQuery("from Warehouse where id = " + id).uniqueResult();
    	}
    
    	@Transactional(readOnly = true)
    	public Collection<Warehouse> getAllWarehouses() throws SQLException, Exception {
    		return sessionFactory.getCurrentSession().createQuery("from Warehouse w").list();
    	}
    
    	@Transactional(readOnly = false)
    	public void deleteWarehouse(Warehouse warehouse) throws SQLException, Exception {
    		sessionFactory.getCurrentSession().delete(warehouse);
    	}
    }
    

    Тесты

    TestItem.java

    package com.devblogs.test;
    
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
    import com.devblogs.dao.ItemDao;
    import com.devblogs.model.Item;
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNull;
    
    @ContextConfiguration("classpath:context.xml")
    public class TestItem extends AbstractJUnit4SpringContextTests {
    	@Autowired
    	private ItemDao itemDao;
    	
    	@Test
        public void testInsertFind() {
    		// Создать тестовый объект
            Item item = new Item();
            item.setName("zheka");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Item i = itemDao.addItem(item);
    	        // Вытащить тестовый объект из базы данных
    	        Item itemFromDb = itemDao.getItemById(i.getId());
    	        // Сравнить вытащенный объект из базы данных с тестовым объектом
    	        assertEquals(item, itemFromDb);
    	        // Удалить тестовый объект из базы данных
    	        itemDao.deleteItem(itemFromDb);
            } catch (Exception e) {
            	e.printStackTrace();
            }
    	}
    	
    	@Test
    	public void testInsertFindUpdate() {
    		// Создать тестовый объект
            Item item = new Item();
            item.setName("zheka");
            try {
            	// Сохранить тестовый объект в базе данных
                Item i = itemDao.addItem(item);
                // Вытащить тестовый объект из базы данных
                Item itemFromDb = itemDao.getItemById(i.getId());
                // Обновить в вытащенном объекте поле name
                itemFromDb.setName("vasya");
                // Записать обновленый тестовый объект в базу данных
    	        itemDao.updateItem(itemFromDb);
    	        // После обновления повторно вытащить тестовый объект из базы данных
    	        Item updatedItemFromDb = itemDao.getItemById(itemFromDb.getId());
    	        // Сравнить тестовый обновленный объект с повторно вытащенным
    	        assertEquals(itemFromDb, updatedItemFromDb);
    	        // Удалить тестовый объект из базы данных
    	        itemDao.deleteItem(updatedItemFromDb);
            } catch (Exception e) {
            	e.printStackTrace();
            }
    	}
    	
    	@Test
        public void testDelete() {
    		// Создать тестовый объект
            Item item = new Item();
            item.setName("test message");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Item i = itemDao.addItem(item);
    	        // Вытащить тестовый объект из базы данных
    	        Item itemToDelete = itemDao.getItemById(i.getId());
    	        // Удалить тестовый объект из базы данных
    	        itemDao.deleteItem(itemToDelete);
    	        // Найти удаленный объект в базе данных
    	        Item itemAfterDeleting = itemDao.getItemById(i.getId());
    	        // Сравнить вытащенный объект после удаления из базы данных на null
    	        assertNull(itemAfterDeleting);
            } catch (Exception e) {
            	e.printStackTrace();
            }
    	}
    }
    

    TestProvider.java

    package com.devblogs.test;
    
    import java.util.HashSet;
    import java.util.Set;
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
    import com.devblogs.dao.ItemDao;
    import com.devblogs.dao.ProviderDao;
    import com.devblogs.model.Item;
    import com.devblogs.model.Provider;
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNull;
    
    @ContextConfiguration("classpath:context.xml")
    public class TestProvider extends AbstractJUnit4SpringContextTests {
    	@Autowired
    	private ProviderDao providerDao;
    	@Autowired
    	private ItemDao itemDao;
    
    	@Test
    	public void testInsertProviderWithItems() {
    		// Создать тестовый объект Provider
    		Provider provider = new Provider();
    		provider.setName("test provider");
    
    		// Создать тестовый объекты Item
    		Set<Item> items = new HashSet<Item>();
    
    		Item item1 = new Item();
    		item1.setName("item1");
    		Item item2 = new Item();
    		item2.setName("item2");
    		Item item3 = new Item();
    		item3.setName("item3");
    		Item item4 = new Item();
    		item4.setName("item4");
    		Item item5 = new Item();
    		item5.setName("item5");
    
    		items.add(item1);
    		items.add(item2);
    		items.add(item3);
    		items.add(item4);
    		items.add(item5);
    
    		provider.setItems(items);
    
    		try {
    			// Сохранить тестовый объект Provider в базе данных
    			Provider p = providerDao.addProvider(provider);
    			// Вытащить тестовый объект из базы данных
    			Provider providerFromDb = providerDao.getProviderById(p.getId());
    			// Сравнить вытащенный объект из базы данных с тестовым объектом
    			assertEquals(provider, providerFromDb);
    			// Вытащить из вытащенного объекта Provider набор объектов Item
    			Set<Item> itemsFromDb = provider.getItems();
    			// Пройти по каждому объекту Item и сравнить с исходными
    			for (Item itemFromDb : itemsFromDb) {
    				// Проверить входит ли вытащенный объект item из базы данных в
    				// набор items тестового объекта Provider
    				assertEquals(items.contains(itemFromDb), true);
    			}
    			// Удалить тестовый объект Provider из базы данных
    			providerDao.deleteProvider(providerFromDb);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    
    	@Test
    	public void testInsertFind() {
    		// Создать тестовый объект
    		Provider provider = new Provider();
    		provider.setName("test provider");
    		try {
    			// Сохранить тестовый объект в базе данных
    			Provider p = providerDao.addProvider(provider);
    			// Вытащить тестовый объект из базы данных
    			Provider providerFromDb = providerDao.getProviderById(p.getId());
    			// Сравнить вытащенный объект из базы данных с тестовым объектом
    			assertEquals(provider, providerFromDb);
    			// Удалить тестовый объект из базы данных
    			providerDao.deleteProvider(providerFromDb);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	@Test
        public void testInsertFindUpdate() {
            // Создать тестовый объект
            Provider provider = new Provider();
            provider.setName("test provider");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Provider p = providerDao.addProvider(provider);
    	        // Вытащить тестовый объект из базы данных
    	        Provider providerFromDb = providerDao.getProviderById(p.getId());
    	        // Обновить в вытащенном объекте поле name
    	        providerFromDb.setName("other provider");
    	        // Записать обновленый тестовый объект в базу данных
    	        providerDao.updateProvider(providerFromDb);
    	        // После обновления повторно вытащить тестовый объект из базы данных
    	        Provider updatedProviderFromDb = providerDao.getProviderById(providerFromDb.getId());
    	        // Сравнить тестовый обновленный объект с повторно вытащенным
    	        assertEquals(providerFromDb, updatedProviderFromDb);
    	        // Удалить тестовый объект из базы данных
    	        providerDao.deleteProvider(updatedProviderFromDb);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    	
    	@Test
        public void testDelete() {
            // Создать тестовый объект
            Provider provider = new Provider();
            provider.setName("test provider");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Provider p = providerDao.addProvider(provider);
    	        // Вытащить тестовый объект из базы данных
    	        Provider providerFromDb = providerDao.getProviderById(p.getId());
    	        // Удалить тестовый объект из базы данных
    	        providerDao.deleteProvider(providerFromDb);
    	        // Найти удаленный объект в базе данных
    	        Provider providerAfterDeleting = providerDao.getProviderById(providerFromDb.getId());
    	        // Сравнить вытащенный объект после удаления из базы данных на null
    	        assertNull(providerAfterDeleting);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    }
    

    TestWarehouse.java

    package com.devblogs.test;
    
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
    import com.devblogs.dao.WarehouseDao;
    import com.devblogs.model.Warehouse;
    import static org.junit.Assert.assertEquals;
    import static org.junit.Assert.assertNull;
    
    @ContextConfiguration("classpath:context.xml")
    public class TestWarehouse extends AbstractJUnit4SpringContextTests {
    	@Autowired
    	private WarehouseDao warehouseDao;
    	
    	@Test
        public void testInsertFind() {
            // Создать тестовый объект
            Warehouse warehouse = new Warehouse();
            warehouse.setAddress("ul. Moskovskaya, 1");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Warehouse w = warehouseDao.addWarehouse(warehouse);
    	        // Вытащить тестовый объект из базы данных
    	        Warehouse warehouseFromDb = warehouseDao.getWarehouseById(w.getId());
    	        // Сравнить вытащенный объект из базы данных с тестовым объектом
    	        assertEquals(warehouse, warehouseFromDb);
    	        // Удалить тестовый объект из базы данных
    	        warehouseDao.deleteWarehouse(warehouseFromDb);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    	
    	@Test
        public void testInsertFindUpdateDelete() {
            // Создать тестовый объект
            Warehouse warehouse = new Warehouse();
            warehouse.setAddress("ul. Moskovskaya, 1");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Warehouse w = warehouseDao.addWarehouse(warehouse);
    	        // Вытащить тестовый объект из базы данных
    	        Warehouse warehouseFromDb = warehouseDao.getWarehouseById(w.getId());
    	        //Обновить в вытащенном объекте поле address
    	        warehouseFromDb.setAddress("ul. Leningradskaya, 4");
    	        // Записать обновленый тестовый объект в базу данных
    	        warehouseDao.updateWarehouse(warehouseFromDb);
    	        // После обновления повторно вытащить тестовый объект из базы данных
    	        Warehouse updatedWarehouseFromDb = warehouseDao.getWarehouseById(warehouseFromDb.getId());
    	        // Сравнить тестовый обновленный объект с повторно вытащенным
    	        assertEquals(warehouseFromDb, updatedWarehouseFromDb);
    	        // Удалить тестовый объект из базы данных
    	        warehouseDao.deleteWarehouse(updatedWarehouseFromDb);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    	
    	@Test
        public void testInsertFindDelete() {
            // Создать тестовый объект
            Warehouse warehouse = new Warehouse();
            warehouse.setAddress("test message");
            try {
    	        // Сохранить тестовый объект в базе данных
    	        Warehouse w = warehouseDao.addWarehouse(warehouse);
    	        // Вытащить тестовый объект из базы данных
    	        Warehouse warehouseToDelete = warehouseDao.getWarehouseById(w.getId());
    	        // Удалить тестовый объект из базы данных
    	        warehouseDao.deleteWarehouse(warehouseToDelete);
    	        // Найти удаленный объект в базе данных
    	        Warehouse warehouseAfterDeleting = warehouseDao.getWarehouseById(w.getId());
    	        // Сравнить вытащенный объект после удаления из базы данных на null
    	        assertNull(warehouseAfterDeleting);
            } catch (Exception e) {
            	e.printStackTrace();
            }
        }
    }
    

    Спринговая конфигурация

    Этот пост отличается от двух предыдущих тем, что мы конфигурируем объекты с помощью спринга. По мимо объектов предметной области, то есть собственно с чем мы работаем, нам нужны еще вспомогательные объекты, которые предоставляют способ работы с объектами предметной области. Hiberante с базой работает через объект Session, а объект Session получаем из объекта SessionFactory, но для того, чтобы объект SessionFactory возвращал нам объект Session, нам нужно объект SessionFacotory настроить. В предыдущих постах мы это делали в контексте самого приложения, сначала создавали файл хибернейтовской конфигурации hibernate.cfg.xml в каталоге resources который ищется по класспасу, а в коде выполнялась такая строчка: new Configuration().configure().buildSessionFactory(), она находит файл конфигурации hibernate.cfg.xml и поднимает объект SessionFactory. Так было в прошлых постах, в этом посте всю хибернейтовскую конфигурацию засунем в спринговый конфигурационный файл, а объект SessionFactory будет подниматься уже из спринга. В Spring существует несколько классов, которые позволяют создать объект SessionFactory в нашем примере это org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean который работает с аннотациями, для него мы пропишем всю необходимую конфигурацию в спринговом конфигурационном файле:

    context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
    	<jdbc:embedded-database id="dataSource" type="H2">
            <jdbc:script location="classpath:scripts/create-data-model.sql"/>
            <jdbc:script location="classpath:scripts/fill-database.sql"/>
        </jdbc:embedded-database>
        
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"/>
        </bean>   
        
    	<tx:annotation-driven/>
    
    	<context:component-scan base-package="com.devblogs" />
    
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="packagesToScan" value="com.devblogs.model"/>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                    <prop key="hibernate.max_fetch_depth">3</prop>
                    <prop key="hibernate.jdbc.fetch_size">50</prop>
                    <prop key="hibernate.jdbc.batch_size">10</prop>
                    <prop key="hibernate.show_sql">false</prop>
                </props>
            </property>        
        </bean>
    
    </beans>
    

    Помчик

    pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.devblogs</groupId>
    	<artifactId>spring-hibernate</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<packaging>jar</packaging>
    
    	<name>spring-hibernate</name>
    	<url>http://maven.apache.org</url>
    
    	<properties>
    		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    		<spring.version>3.2.7.RELEASE</spring.version>
    	</properties>
    
    	<dependencies>
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-entitymanager</artifactId>
    			<version>3.6.7.Final</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-context</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-test</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-jdbc</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework</groupId>
    			<artifactId>spring-orm</artifactId>
    			<version>${spring.version}</version>
    		</dependency>
    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-core</artifactId>
    			<version>3.6.3.Final</version>
    		</dependency>
    		<dependency>
    			<groupId>com.h2database</groupId>
    			<artifactId>h2</artifactId>
    			<version>1.3.160</version>
    		</dependency>
    		<dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.11</version>
    			<scope>test</scope>
    		</dependency>
    	</dependencies>
    </project>
    

    Компиляция и запуск

    Для проверки работоспособности приложения запустим мавенские тесты командой mvn test:

    mvn test
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building spring-hibernate 0.0.1-SNAPSHOT
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ spring-hibernate ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 3 resources
    [INFO]
    [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ spring-hibernate ---
    [INFO] Nothing to compile - all classes are up to date
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ spring-hibernate ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory E:\practice\spring\test\spring-hibernate\src\test\resources
    [INFO]
    [INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ spring-hibernate ---
    [INFO] Nothing to compile - all classes are up to date
    [INFO]
    [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ spring-hibernate ---
    [INFO] Surefire report directory: E:\practice\spring\test\spring-hibernate\target\surefire-reports
    
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running com.devblogs.test.TestItem
    Apr 26, 2016 1:51:05 PM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
    INFO: Could not instantiate TestExecutionListener class [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their dependencies) available.
    Apr 26, 2016 1:51:05 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [context.xml]
    Apr 26, 2016 1:51:05 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.GenericApplicationContext@48778a5d: startup date [Tue Apr 26 13:51:05 EEST 2016]; root of context hierarchy
    Apr 26, 2016 1:51:05 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@17e4a077: defining beans [dataSource,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,itemDaoImpl,providerDaoImpl,warehouseDaoImpl,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,sessionFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
    Apr 26, 2016 1:51:05 PM org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory initDatabase
    INFO: Creating embedded database 'dataSource'
    Apr 26, 2016 1:51:05 PM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript
    INFO: Executing SQL script from class path resource [scripts/create-data-model.sql]
    Apr 26, 2016 1:51:06 PM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript
    INFO: Done executing SQL script from class path resource [scripts/create-data-model.sql] in 119 ms.
    Apr 26, 2016 1:51:06 PM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript
    INFO: Executing SQL script from class path resource [scripts/fill-database.sql]
    Apr 26, 2016 1:51:06 PM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript
    INFO: Done executing SQL script from class path resource [scripts/fill-database.sql] in 14 ms.
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    Apr 26, 2016 1:51:06 PM org.springframework.orm.hibernate3.LocalSessionFactoryBean buildSessionFactory
    INFO: Building new Hibernate SessionFactory
    Apr 26, 2016 1:51:06 PM org.springframework.orm.hibernate3.HibernateTransactionManager afterPropertiesSet
    INFO: Using DataSource [org.springframework.jdbc.datasource.SimpleDriverDataSource@5720be65] of Hibernate SessionFactory for HibernateTransactionManager
    Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.944 sec
    Running com.devblogs.test.TestProvider
    Apr 26, 2016 1:51:07 PM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
    INFO: Could not instantiate TestExecutionListener class [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their dependencies) available.
    Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 sec
    Running com.devblogs.test.TestWarehouse
    Apr 26, 2016 1:51:07 PM org.springframework.test.context.TestContextManager retrieveTestExecutionListeners
    INFO: Could not instantiate TestExecutionListener class [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their dependencies) available.
    Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.021 sec
    
    Results :
    
    Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time: 3.953s
    [INFO] Finished at: Tue Apr 26 13:51:07 EEST 2016
    [INFO] Final Memory: 7M/244M
    [INFO] ------------------------------------------------------------------------
    
    

    Поделиться в социальных сетях

    Опубликовать в Google Plus
    Опубликовать в LiveJournal
    Опубликовать в Мой Мир
    Опубликовать в Одноклассники
    Опубликовать в Яндекс

    Добавить комментарий

    Ваш e-mail не будет опубликован. Обязательные поля помечены *