обратный = «истинный» пример и объяснение

обратный = «истинный» пример и объяснение

Always put inverse=”true” in your collection variable ?
Есть много статей о Hibernate, в которых пытаются объяснить «обратное» с помощью многих «официальных» жаргонов Hibernate, которые очень трудно понять (по крайней мере, для меня). В нескольких статьях они даже предлагали просто забыть об «инверсии» и всегда помещатьinverse=”true” в переменную коллекции.

Это утверждение всегда верно - «положить переменную = true в переменную коллекции», но не закрывайте на это глаза, постарайтесь понять причину, по которой это необходимо для оптимальной производительности Hibernate.

Что такое «обратный»?

Это самое запутанное ключевое слово в Hibernate, по крайней мере, я потратил довольно много времени, чтобы понять его. Ключевое слово «inverse» всегда объявляется в соотношенииone-to-many иmany-to-many (многие-к-одному не имеют обратного ключевого слова), это означает, что какая сторона несет ответственность за отношения.

«Обратный», должен измениться на «владелец отношений»?

В Hibernate только «владелец отношения» должен поддерживать отношения, и создается ключевое слово «инверсия», чтобы определить, какая сторона является владельцем для поддержания отношений. Однако само ключевое слово «inverse» недостаточно подробное, я бы предложил изменить ключевое слово на «relationship_owner».

Короче говоря, обратный = «истина» означает, что это владелец отношения, а обратный = «ложь» (по умолчанию) означает, что это не так.

1. Отношение один ко многим

Это дизайн таблицы отношенийone-to-many, таблица STOCK имеет много вхождений в таблице STOCK_DAILY_RECORD.

one to many relationship

2. Реализация гибернации

См. Реализацию Hibernate в файлах сопоставления XML.

Файл: Stock.java

public class Stock implements java.io.Serializable {
   ...
   private Set stockDailyRecords =
                        new HashSet(0);
   ...

Файл: StockDailyRecord.java

public class StockDailyRecord implements java.io.Serializable {
   ...
   private Stock stock;
   ...

Файл: Stock.hbm.xml


    
    ...
    
        
            
        
        
    
    ...

Файл: StockDailyRecord.hbm.xml


  
  ...
  
       
  
  ...

3. обратный = правда / ложь

Обратное ключевое слово применяется в отношении один ко многим. Вот вопрос, если операция сохранения или обновления выполняется в объекте «Stock», следует ли обновить отношение «stockDailyRecords»?

Файл: Stock.hbm.xml

    
    ...
    
        
            
        
        
    
    ...

1. инверсия = "истина"

Если значение inverse = «true» в переменной set, это означает, что «stock_daily_record» является владельцем отношения, поэтому Stock НЕ ОБНОВЛЯЕТ отношение.


    ...
    

2. инверсия = "ложь"

Если значение inverse = «false» (по умолчанию) в переменной set, это означает, что «stock» является владельцем отношения, и Stock обновит отношение.


    ...
    

Смотрите больше примеров ниже:

4. пример = "ложь"

Если ключевое слово «обратный» не определено, будет использовано обратное = «ложное», что



    ...
    

Это означает, что «сток» является владельцем отношений, и он будет поддерживать отношения.

Вставить пример…

При сохранении объекта «Stock» Hibernate сгенерирует три оператора SQL, две вставки и одно обновление.

    session.beginTransaction();

    Stock stock = new Stock();
    stock.setStockCode("7052");
    stock.setStockName("PADINI");

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

    stockDailyRecords.setStock(stock);
    stock.getStockDailyRecords().add(stockDailyRecords);

    session.save(stock);
    session.save(stockDailyRecords);

    session.getTransaction().commit();

Выход…

Hibernate:
    insert
    into
        exampledb.stock
        (STOCK_CODE, STOCK_NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)
Hibernate:
    update
        exampledb.stock_daily_record
    set
        STOCK_ID=?
    where
        RECORD_ID=?

Stock обновит «stock_daily_record.STOCK_ID» с помощью переменной Set (stockDailyRecords), потому что Stock является владельцем отношения.

Note
Третий оператор действительно НЕ нужен.

Пример обновления…

Когда объект «Stock» обновляется, Hibernate сгенерирует два оператора SQL, один для вставки и один для обновления.

    session.beginTransaction();

    Stock stock = (Stock)session.get(Stock.class, 57);

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

    stockDailyRecords.setStock(stock);
    stock.getStockDailyRecords().add(stockDailyRecords);

    session.save(stockDailyRecords);
    session.update(stock);

    session.getTransaction().commit();

Выход…

Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)
Hibernate:
    update
        exampledb.stock_daily_record
    set
        STOCK_ID=?
    where
        RECORD_ID=?

Note
Опять же, третий оператор НЕ нужен.

5. пример = "истина"

Если ключевое слово «inverse = true» определено:



    ...
    

Теперь это означает, что «stockDailyRecords» является владельцем отношения, а «акции» не будут поддерживать отношения.

Вставить пример…

При сохранении объекта «Stock» Hibernate сгенерирует два оператора вставки SQL.

    session.beginTransaction();

    Stock stock = new Stock();
    stock.setStockCode("7052");
    stock.setStockName("PADINI");

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

    stockDailyRecords.setStock(stock);
    stock.getStockDailyRecords().add(stockDailyRecords);

    session.save(stock);
    session.save(stockDailyRecords);

    session.getTransaction().commit();

Вывод …

Hibernate:
    insert
    into
        exampledb.stock
        (STOCK_CODE, STOCK_NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)

Пример обновления…

При обновлении объекта «Stock» Hibernate сгенерирует одну инструкцию SQL.

    session.beginTransaction();

    Stock stock = (Stock)session.get(Stock.class, 57);

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

    stockDailyRecords.setStock(stock);
    stock.getStockDailyRecords().add(stockDailyRecords);

    session.save(stockDailyRecords);
    session.update(stock);

    session.getTransaction().commit();

Выход…

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

inverse vs cascade
Многие люди любят сравнивать инверсию и каскад, но это совершенно разные понятия, см.differential here.

Заключение

Понимание «обратного» необходимо для оптимизации кода Hibernate, оно помогает избежать многих ненужных операторов обновления, таких как «пример вставки и обновления для обратного = ложного» выше. Наконец, постарайтесь запомнить обратное = «true», означающее, что это владелец отношения, который будет управлять отношениями.