Hibernate изменчивый пример (класс и коллекция)
В спящем режиме «mutable» по умолчанию имеет значение «true» в классе и связанной с ним коллекции, это означает, что класс или коллекция могут добавлять, обновлять и удалять. С другой стороны, если изменяемое значение изменено на false, оно имеет другое значение в классе и связанной коллекции. Давайте возьмем несколько примеров, чтобы понять больше об этом.
Пример гибернации один ко многим
Я возьму этотone-to-many example для изменяемой демонстрации. В этом файле сопоставления Stock принадлежит многим StockDailyRecord.
......
Как объявить изменчивым?
Mutable поддерживает как файл сопоставления XML, так и аннотации.
1. XML-файл отображения
В файле сопоставления ключевое слово «mutable» используется для реализации изменяемой функции.
......
2. аннотирование
В аннотации ключевое слово изменяется на @Immutable (mutable = '' false ').
... @Entity @Immutable @Table(name = "stock", catalog = "example") public class Stock implements java.io.Serializable { ... @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock") @Immutable public SetgetStockDailyRecords() { return this.stockDailyRecords; } ...
Изменчивый в классе
Если в элементе класса объявлено mutable = «false» или @Immutable, это означаетupdates to this class will be ignored, but no exception is thrown, only the add and delete operation are allow.
1. Тестовая вставка
Stock stock = new Stock(); stock.setStockCode("7277"); stock.setStockName("DIALOG"); session.save(stock);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в классе.
Output
Hibernate: insert into example.stock (STOCK_CODE, STOCK_NAME) values (?, ?)
если в классе объявлено mutable = «false» или @Immutable.
Output
Hibernate: insert into example.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);
если mutable = «true» или @Immutable не объявлен в классе.
Output
Hibernate: select ...from example.stock stock0_ where stock0_.STOCK_CODE='7277' Hibernate: update example.stock set STOCK_CODE=?,STOCK_NAME=? where STOCK_ID=?
если в классе объявлено mutable = «false» или @Immutable.
Output
Hibernate: select ...from example.stock stock0_ where stock0_.STOCK_CODE='7277'
Изменяемый в классе не позволяет приложению обновлять его, операция «обновления» будет проигнорирована, и исключение не будет создано.
3. Тест удалить
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); session.delete(stock);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в классе.
Output
Hibernate: delete from example.stock where STOCK_ID=?
если в классе объявлено mutable = «false» или @Immutable.
Output
Hibernate: delete from example.stock where STOCK_ID=?
Изменяемый в классе не влияет на операцию «удалить».
Изменчивый в коллекции
Если в коллекции объявлено mutable = «false» или @Immutable, это означаетadd and delete-orphan are not allow in this collection, with exception throw, only update and ‘cascade delete all’ are allow.
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);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в коллекции.
Output
Hibernate: insert into example.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
если в коллекции объявлено mutable = «false» или @Immutable.
Output
Exception in thread "main" org.hibernate.HibernateException: changed an immutable collection instance: [com.example.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);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в коллекции.
Output
Hibernate: update example.stock_daily_record set PRICE_CHANGE=?, ... where DAILY_RECORD_ID=?
если в коллекции объявлено mutable = «false» или @Immutable.
Output
Hibernate: update example.stock_daily_record set PRICE_CHANGE=?, ... where DAILY_RECORD_ID=?
Изменяемый в коллекции не влияет на операцию «обновления».
3. Тест удалить-сирота
Предположим, чтоcascade delete-orphan включен.
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);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в коллекции.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=?
если в коллекции объявлено mutable = «false» или @Immutable.
Output
Exception in thread "main" org.hibernate.HibernateException: changed an immutable collection instance: [com.example.common.Stock.stockDailyRecords#111]
Mutable in collection не допускает операцию «delete-orphan», выдается исключение.
4. Тест удалить
Предположим, что каскадное удаление включено.
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); session.saveOrUpdate(stock);
если mutable = «true» (по умолчанию) или @Immutable не объявлен в коллекции.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=? Hibernate: delete from example.stock where STOCK_ID=?
если в коллекции объявлено mutable = «false» или @Immutable.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=? Hibernate: delete from example.stock where STOCK_ID=?
Изменяемый в коллекции не влияет на операцию «удалить», если родительский элемент удален, все его дочерние элементы также будут удалены, даже если он изменен.
Почему изменчивый?
Изменяемый может избежать многих непреднамеренных операций с базой данных, таких как добавление, обновление или удаление некоторых записей, которые не должны быть. Кроме того, согласно документации Hibernate, мутабельный do имеет некоторые незначительные оптимизации производительности, поэтому всегда рекомендуется анализировать ваши отношения сопоставления и реализовывать изменяемый по мере необходимости.
Резюме
1. mutable = «false» или @Immutable объявлен в классе
это означает, что обновления этого класса будут игнорироваться, но исключение не выдается, разрешены только операции добавления и удаления.
В классе с mutable = "false" - insert = allow, delete = allow, update = not allow
2. mutable = «false» или @Immutable объявлен в коллекции
это означает, что add и delete-orphan не разрешены в этой коллекции, за исключением throw, разрешено только обновление. Однако, если включено каскадное удаление, при удалении родителя будет также удален весь его дочерний элемент, даже если он изменчивый.
В коллекции с mutable = ”false” - insert = not allow, delete-orphan = not allow, delete = allow, update = allow
Полностью неизменным?
Может ли класс быть абсолютно неизменным для каких-либо действий? Да, поместите mutable = ”false” для всех его отношений (вставка = не разрешать, delete-orphan = не разрешать) и mutable = ”false” для класса, который вы хотите изменить (update = не разрешать). Теперь у вас есть полностью неизменяемый класс, однако, если включена опция каскадного удаления, при удалении родителя вашего неизменяемого класса ваш неизменяемый класс также будет удален.