Рубрики
Без рубрики

Пример изменяемого режима гибернации (класс и коллекция)

– Пример изменяемого режима гибернации (класс и коллекция)

В режиме гибернации ” изменяемый ” по умолчанию имеет значение “true” в классе и связанной с ним коллекции, это означает, что классу или коллекции разрешено добавлять, обновлять и удалять. С другой стороны, если изменяемый параметр изменен на false, он имеет другое значение в классе и связанной с ним коллекции. Давайте приведем несколько примеров, чтобы лучше понять это.

Спящий режим один ко многим пример

Я возьму этот пример один ко многим для демонстрации изменчивости. В этом файле сопоставления Акции принадлежат многим учетным записям.


...

    
        
            
                
            
            
        
    
...    

Как объявить изменяемым?

“Изменяемый” поддерживается как в файле сопоставления XML, так и в аннотации.

1. Файл сопоставления XML

В файле сопоставления ключевое слово ‘ изменяемый ‘ используется для реализации изменяемой функции.


...

    
        
            
                
            
            
        
    
...    

2. Аннотация

В аннотации ключевое слово изменено на @Неизменяемый).

...
@Entity
@Immutable
@Table(name = "stock", catalog = "mkyong")
public class Stock implements java.io.Serializable {
...
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
	@Immutable
	public Set getStockDailyRecords() {
		return this.stockDailyRecords;
	}
...

Изменяемый в классе

Если or @Immutable объявлен в элементе класса, это означает, что обновления для этого класса будут игнорироваться, но никаких исключений не будет, разрешены только операции добавления и удаления .

1. Тестовая вставка

Stock stock = new Stock();
stock.setStockCode("7277");
stock.setStockName("DIALOG");
session.save(stock);

если (по умолчанию) или нет @Неизменяемый объявлен в классе. Выход

Hibernate: 
    insert into mkyong.stock (STOCK_CODE, STOCK_NAME) 
    values (?, ?)

если или @Неизменяемый объявлен в классе. Выход

Hibernate: 
    insert into mkyong.stock (STOCK_CODE, STOCK_NAME) 
    values (?, ?)

Изменяемый в классе не влияет на операцию “вставка”.

2. Тестовое обновление

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
stock.setStockName("DIALOG123");
session.saveOrUpdate(stock);

если или нет @Immutable объявлен в классе. Выход

Hibernate: 
    select ...from mkyong.stock stock0_ 
    where stock0_.STOCK_CODE='7277'

Hibernate: 
    update mkyong.stock 
    set STOCK_CODE=?,STOCK_NAME=? 
    where STOCK_ID=?

если или @Неизменяемый объявлен в классе. Выход

Hibernate: 
    select ...from mkyong.stock stock0_ 
    where stock0_.STOCK_CODE='7277'

Изменяемый в классе не позволяет приложению обновлять его, операция “обновление” будет проигнорирована, и исключение не будет выдано

3. Тестовое удаление

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.delete(stock);

если (по умолчанию) или нет @Неизменяемый объявлен в классе. Выход

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

если или @Неизменяемый объявлен в классе. Выход

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

Изменяемый в классе не влияет на операцию “удалить”.

Изменяемый в коллекции

Если или @Неизменяемый объявлен в коллекции, это означает, что добавление и удаление-сироты не разрешены в этой коллекции, за исключением исключения, разрешено только обновление и “каскадное удаление всех”. .

1. Тестовая вставка

Предположим, что каскадная вставка включена.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = new StockDailyRecord();
sdr.setDate(new Date());        
sdr.setStock(stock);
stock.getStockDailyRecords().add(sdr);
session.save(stock);

если (по умолчанию) или нет @Immutable объявлен в коллекции. Выход

Hibernate: 
    insert into mkyong.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) 
    values (?, ?, ?, ?, ?, ?)

если или @Неизменяемый объявлен в коллекции. Выход

Exception in thread "main" org.hibernate.HibernateException: 
changed an immutable collection instance: 
[com.mkyong.common.Stock.stockDailyRecords#111]

Изменяемый в коллекции не разрешает операцию “добавить”, возникнет исключение.

2. Тестовое обновление

Предположим, что каскадное обновление включено.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
sdr.setPriceChange(new Float(1.30));
session.saveOrUpdate(stock);

если (по умолчанию) или нет @Immutable объявлен в коллекции. Выход

Hibernate: 
    update mkyong.stock_daily_record 
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

если или @Неизменяемый объявлен в коллекции. Выход

Hibernate: 
    update mkyong.stock_daily_record 
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

Изменяемый в коллекции не влияет на операцию “обновление”.

3. Тестовое удаление-сирота

Предположим, что каскадное удаление-сирота включено.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next();
stock.getStockDailyRecords().remove(sdr);
session.saveOrUpdate(stock);

если (по умолчанию) или нет @Immutable объявлен в коллекции. Выход

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

если или @Неизменяемый объявлен в коллекции. Выход

Exception in thread "main" org.hibernate.HibernateException: 
changed an immutable collection instance: 
[com.mkyong.common.Stock.stockDailyRecords#111]

Изменяемый в коллекции не разрешает операцию “удалить-сироту”, возникнет исключение.

4. Тестовое удаление

Предположим, что каскадное удаление включено.

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.saveOrUpdate(stock);

если (по умолчанию) или нет @Immutable объявлен в коллекции. Выход

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

если или @Неизменяемый объявлен в коллекции. Выход

Hibernate: 
    delete from mkyong.stock_daily_record 
    where DAILY_RECORD_ID=?

Hibernate: 
    delete from mkyong.stock 
    where STOCK_ID=?

Изменяемый в коллекции не влияет на операцию “удалить”, если родительский элемент удален, все его дочерние элементы также будут удалены, даже если они изменяемы.

Почему изменчивый?

Изменяемый может избежать многих непреднамеренных операций с базой данных, таких как добавление, обновление или удаление некоторых записей, которых не должно быть. Кроме того, согласно документации Hibernate, изменяемый do имеет некоторые незначительные оптимизации производительности, всегда рекомендуется анализировать ваши отношения сопоставления и внедрять изменяемый по мере необходимости.

Резюме

1. или @Неизменяемый объявлен в классе

это означает, что обновления этого класса будут игнорироваться, но никаких исключений не будет, разрешены только операции добавления и удаления.

В классе с –, , позволять

2. или @Неизменяемый объявлен в коллекции

это означает, что добавление и удаление-сироты не разрешены в этой коллекции, за исключением исключения, разрешено только обновление. Однако, если включено каскадное удаление, при удалении родителя все его дочерние элементы также будут удалены, даже если они изменчивы.

В коллекции с – разрешить, разрешить, ,

Полностью неизменный?

Может ли класс быть полностью неизменяемым для любых действий? Да, поставьте a для всех разрешенных отношений, разрешите), и a для класса, который вы хотите разрешить неизменяемым). Теперь у вас есть полностью неизменяемый класс, однако, если включена опция каскадного удаления, при удалении родительского элемента вашего неизменяемого класса ваш неизменяемый класс также будет удален.

Ссылка

1. Ссылка

Оригинал: “https://mkyong.com/hibernate/hibernate-mutable-example-class-and-collection/”