Как я могу определить стратегию, используемую JPA, чтобы поймать новый идентификатор для объекта? [Дубликат]

Ниже приведены пять вариантов достижения этого макета:

  • Позиционирование CSS
  • Flexbox с невидимым элементом DOM
  • Flexbox с невидимым псевдоэлементом
  • Flexbox с flex: 1
  • CSS Grid Layout

Метод # 1: Свойства позиционирования CSS

Применить position: relative к контейнеру гибкого диска.

Применить position: absolute к пункту D.

Теперь этот элемент абсолютно расположен внутри контейнера flex.

Подробнее , элемент D удаляется из потока документов, но остается в пределах ближайшего расположенного предка .

Используйте свойства смещения CSS top и right для перемещения этого элемента в положение

li:last-child {
  position: absolute;
  top: 0;
  right: 0;
  background: #ddd;
}
ul {
  position: relative;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p {
  text-align: center;
  margin-top: 0;
}
span {
  background-color: aqua;
}
  • A
  • B
  • C
  • D

true center

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


Метод №2: Flex Auto Margins & amp; Invisible Flex Item (элемент DOM)

С комбинацией полей auto и нового невидимого элемента гибкости макет может быть достигнут.

новый элемент гибкости идентичен элементу D и расположен на противоположном конце (левый край).

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

Новый элемент удаляется из представления с помощью visibility: hidden.

Короче:

  • Создайте дубликат элемента D.
  • Поместите его в начало списка.
  • Используйте flex auto, чтобы сохранить A, B и C в центре, причем оба элемента D создают одинаковый баланс с обоих концов.
  • Примените visibility: hidden к дубликату D

li:first-child {
  margin-right: auto;
  visibility: hidden;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
  • D
  • A
  • B
  • C
  • D

true center


Способ №3: Автоматические поля Flex и amp; Invisible Flex Item (псевдоэлемент)

Этот метод аналогичен # 2, за исключением того, что он очищен семантически, и ширина D должна быть известна.

  • Создайте псевдо-элемент с той же шириной, что и D.
  • Поместите его в начале контейнера с помощью ::before.
  • Используйте поля flex auto, чтобы сохранить A , B и C идеально центрированы, причем элементы псевдо и D создают одинаковый баланс с обоих концов.

ul::before {
  content:"D";
  margin: 1px auto 1px 1px;
  visibility: hidden;
  padding: 5px;
  background: #ddd;
}
li:last-child {
  margin-left: auto;
  background: #ddd;
}
ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
  • A
  • B
  • C
  • D

true center


Способ №4: Добавить flex: 1 в левый и правый элементы

Начиная с метода № 2 или № 3 выше, вместо того, чтобы беспокоиться о равной ширине для левой и правой правильные элементы для поддержания равного баланса, просто дайте каждому flex: 1. Это заставит их обоих потреблять свободное пространство, центрируя средний элемент.

Затем вы можете добавить display: flex к отдельным элементам, чтобы выровнять их содержимое.

ПРИМЕЧАНИЕ об использовании этого метода с min-height: В настоящее время в Chrome, Firefox, Edge и, возможно, в других браузерах правило сокращения flex: 1 ломается до этого:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

Этот процентный блок (%) в flex-basis вызывает это метод прерывания, когда min-height используется в контейнере. Это связано с тем, что, как правило, в процентах высоты для детей требуется явное свойство свойства height для родителя.

Это старое правило CSS, относящееся к 1998 году ( CSS Level 2 ), который по-прежнему действует во многих браузерах в той или иной степени. Подробнее см. Здесь здесь и здесь .

Вот иллюстрация проблемы, опубликованной в комментариях пользователя user2651804 :

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container>div {
  background: orange;
  margin: 5px;
}

#flex-container>div:first-child {
  flex: 1;
}

#flex-container::after {
  content: "";
  flex: 1;
}
very long annoying text that will add on top of the height of its parent
center

Решение состоит в том, чтобы не использовать процентную единицу. Попробуйте px или просто ничего (, что действительно рекомендует спецификация , несмотря на то, что по крайней мере некоторые из основных браузеров приложили процентную единицу по любой причине).

#flex-container {
  display: flex;
  flex-direction: column;
  background: teal;
  width: 150px;
  min-height: 80vh;
  justify-content: space-between;
}

#flex-container > div {
  background: orange;
  margin: 5px;
}


/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */

#flex-container > div:first-child {
  flex: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex: 1;
  flex-basis: 0;
}


/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY

#flex-container > div:first-child {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

#flex-container::after {
  content: "";
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}
 */
very long annoying text that will add on top of the height of its parent
center

Метод №5: Макет сетки CSS

Это может быть самый чистый и эффективный метод. Нет необходимости в абсолютном позиционировании, поддельных элементах или других хакерах.

Просто создайте сетку с несколькими столбцами. Затем разместите свои позиции в середине и в конце столбцов. В принципе, просто оставьте первый столбец пустым.

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
  • A
  • B
  • C
  • D

| true center |

24
задан RubioRic 15 May 2016 в 19:11
поделиться

9 ответов

Создайте свое имя последовательности в Oracle, например, contact_seq. В вашем классе POJO. Определите следующую аннотацию для вашей последовательности.

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_seq_gen")
@SequenceGenerator(name="my_seq_gen", sequenceName="contacts_seq")
5
ответ дан Aurasphere 18 August 2018 в 05:32
поделиться

По умолчанию Hibernate использует генератор последовательности HiLo, который, если у вас нет особых потребностей, хорош (производительность разумна). Вы можете узнать больше об этом в моем блоге здесь

Eyal

0
ответ дан Eyal Lupu 18 August 2018 в 05:32
поделиться
  • 1
    Любая идея сменить алгоритм, сказав, что вместо объединения hilo с использованием аннотаций JPA? – user 21 October 2013 в 16:57

У меня была такая же проблема при обновлении с 3.5.5 до 5.0.6.Final.

Я решил ее переустановить сопоставление в файле HBM с:

    <generator class="sequence">
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>

:

    <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator"> 
        <param name="prefer_sequence_per_entity">true</param> 
        <param name="optimizer">none</param>
        <param name="increment_size">1</param>
        <param name="sequence_name">PRODUCT_ID_SEQ</param>
    </generator>
5
ответ дан jvergara 18 August 2018 в 05:32
поделиться
  • 1
    Нужно ли устанавливать increment_size в 1? Разве это не значение по умолчанию? – Florian F 26 October 2017 в 09:12

Если вы используете javax.persistence.SequenceGenerator, hibernate используйте hilo и, возможно, создадите большие пробелы в последовательности. Существует сообщение, посвящённое этой проблеме: https://forum.hibernate.org/viewtopic.php?t=973682

есть два способа исправить эту проблему

  1. В аннотации SequenceGenerator добавьте allocSize = 1, initialValue = 1
  2. вместо использования javax.persistence.SequenceGenerator, используйте org.hibernate.annotations, например: @ javax.persistence .SequenceGenerator (name = "Question_id_sequence", sequenceName = "S_QUESTION") @ org.hibernate.annotations.GenericGenerator (name = "Question_id_sequence", strategy = "sequence", parameters = {@Parameter (name = "sequence", value = «S_QUESTION»)})

Я тестировал оба способа, которые работают отлично.

4
ответ дан Maninder 18 August 2018 в 05:32
поделиться

Ответ на исходный вопрос:

@SequenceGenerator(name="EL_SEQ", sequenceName="EL_SEQ",allocationSize=1)

Это значение allocationSize устанавливает значение для увеличения на.

24
ответ дан Mike Demenok 18 August 2018 в 05:32
поделиться
  • 1
    Активировано, потому что это правильное решение JPA, а не Hibernate. Однако allocSize = 1 означает, что число необходимо получить из базы данных для каждой вставки, а не для кэширования большого количества идентификаторов одновременно, поэтому оно имеет очень маленькую деградацию производительности. – shonky linux user 31 July 2013 в 00:58

Я не использую аннотации, это то, что у меня есть в моем * .hbm.xml:

<id name="id" type="java.lang.Integer">
    <column name="ID_PRODUCT" />
    <generator class="sequence-identity" >
        <param name="sequence">PRODUCT_ID_SEQ</param>
    </generator>
</id>

. Вы можете легко сопоставить это с аннотациями. Генератор sequence-identity использует автоинкремент с последовательностями.

17
ответ дан rsilva4 18 August 2018 в 05:32
поделиться
  • 1
    Это правильный способ сделать это (с xml) см. Ниже для примера с аннотациями – Tristan 14 August 2011 в 09:40
  • 2
    +1 и не забудьте добавить <property name="hibernate.jdbc.use_get_generated_keys">true</property> в ваш файл hibernate.cfg.xml. – Withheld 13 February 2014 в 15:37

allocSize и incrementBy - совершенно разные вещи.

Спящий режим, конечно, использует вашу последовательность, созданную в БД, но в зависимости от allocSize вы можете найти пробел в сгенерированном значении.

Например, Предположим, что текущее значение последовательности равно 5, увеличивается на 1 в db и присваивает значение по умолчанию 50.

Теперь вы хотите сохранить коллекцию из 3 элементов через спящий режим, тогда Hibernate назначит сгенерированный идентификатор 250, 251, 252

Это для целей оптимизации. Hibernate не нужно возвращаться к db и получать следующее добавочное значение.

Если вы не хотите, чтобы эта настройка allocationSize = 1, как уже было сказано, выполнит цель

2
ответ дан shakhawat 18 August 2018 в 05:32
поделиться

Я использую следующее на PostgreSQL и отлично работает.

 @Id
 @GeneratedValue(generator = "my_gen")
 @SequenceGenerator(name = "my_gen", sequenceName = "my_seq_in_db")
 private int userId;
2
ответ дан Summer 18 August 2018 в 05:32
поделиться

Вот рабочий пример с аннотациями, таким образом, будет использоваться существующая последовательность БД (вы также можете использовать стратегию «последовательность», но с меньшей производительностью при вставке):

@Entity
@Table(name = "USER")
public class User {

    // (...)

    @GenericGenerator(name = "generator", strategy = "sequence-identity", parameters = @Parameter(name = "sequence", value = "USER_SEQ"))
    @Id
    @GeneratedValue(generator = "generator")
    @Column(name = "ID", unique = true, nullable = false, precision = 22, scale = 0)
    public Long getId() {
        return this.id;
    }
8
ответ дан Tristan 18 August 2018 в 05:32
поделиться
  • 1
    Я обнаружил, что при использовании этого метода он работал, но моя база данных увеличивала значение id на 2 вместо 1. Любые идеи, почему? – user898465 16 October 2013 в 01:05
  • 2
    проверьте свое определение последовательности в Oracle, у вас может быть что-то вроде «CREATE SEQUENCE my_sequence START WITH 1 INCREMENT BY 2». – Tristan 17 October 2013 в 07:59
Другие вопросы по тегам:

Похожие вопросы: