«Отключенный объект, переданный для сохранения ошибки» с кодом JPA / EJB

Я пытаюсь запустить этот базовый код JPA / EJB:

public static void main(String[] args){ UserBean user = new UserBean(); user.setId(1); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); } 

Я получаю эту ошибку:

 javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.JPA.Database 

Есть идеи?

Я ищу в Интернете, и причина, по которой я нашел, была:

Это было вызвано тем, как вы создали объекты, т. Е. Если вы явно задали свойство ID. Исправлено удаление идентификатора.

Но я не понял, что мне нужно изменить, чтобы заставить код работать?

ERD

Допустим, у вас есть два объекта Album и Photo . Альбом содержит много фотографий, так что это отношения от одного до многих.

Класс альбома

 @Entity public class Album { @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer albumId; String albumName; @OneToMany(targetEntity=Photo.class,mappedBy="album",cascade={CascadeType.ALL},orphanRemoval=true) Set photos = new HashSet(); } 

Фотоclass

 @Entity public class Photo{ @Id @GeneratedValue(strategy=GenerationType.AUTO) Integer photo_id; String photoName; @ManyToOne(targetEntity=Album.class) @JoinColumn(name="album_id") Album album; } 

Перед тем, как продолжить или слить, нужно установить ссылку «Альбом» на каждой фотографии.

  Album myAlbum = new Album(); Photo photo1 = new Photo(); Photo photo2 = new Photo(); photo1.setAlbum(myAlbum); photo2.setAlbum(myAlbum); 

Вот как присоединить связанный объект до того, как вы будете продолжать или сливаться.

Ошибка возникает из-за того, что установлен идентификатор объекта. Спящий режим различает переходные и удаленные объекты и persist работать только с переходными объектами. Если persist завершает, объект отделяется (что будет связано с тем, что ID установлен), он вернет ошибку «отсоединенный объект, прошедший для сохранения». Вы можете найти более подробную информацию здесь и здесь .

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

Удалить

 user.setId(1); 

потому что он автоматически генерируется в БД и продолжает команду persist.

Я получил ответ, я использовал:

 em.persist(user); 

Я использовал слияние вместо сохранения:

 em.merge(user); 

Но не знаю, почему упорство не получилось. 🙁

если вы используете для создания страtagsи id = GenerationType.AUTO в своей организации.

Заменяет user.setId (1) на user.setId (null) , и проблема решена.

Я знаю, что он слишком поздно и уверен, что каждый получил ответ. Но немного больше, чтобы добавить к этому: когда установлен GenerateType, persist () на объекте должен получить генерируемый идентификатор.

Если уже установлено значение Id для пользователя, hibernate рассматривает его как сохраненную запись, и поэтому он рассматривается как отсоединенный.

если id равен null – в этой ситуации исключение с нулевым указателем возникает, когда тип AUTO или IDENTITY и т. д., если идентификатор не генерируется из таблицы или отдельной строки и т. д.

design: это происходит, когда таблица имеет свойство bean как первичный ключ. GenerateType должен быть установлен только тогда, когда идентификатор автогенерируется. удалите это, и вставка должна работать с указанным пользователем идентификатором. (это плохой дизайн, чтобы иметь свойство, отображаемое в поле первичного ключа)

Здесь .persist () будет только вставлять запись. Если мы используем .merge (), он проверит, существует ли какая-либо запись с текущим идентификатором. Если она существует, она будет обновляться, иначе она будет вставлять новую запись.

У меня была эта проблема, и она была вызвана кешем второго уровня:

  1. Я сохранял объект, использующий hibernate
  2. Затем я удалил строку, созданную из отдельного процесса, который не взаимодействовал с кешем второго уровня
  3. Я сохранял другой объект с тем же идентификатором (мои значения идентификатора не генерируются автоматически)

Следовательно, поскольку кеш не был аннулирован, hibernate предположил, что он имеет дело с отдельным экземпляром того же объекта.

Если вы установите id в своей базе данных как первичный ключ и автоинкремент, то эта строка кода неверна:

 user.setId(1); 

Попробуйте следующее:

 public static void main(String[] args){ UserBean user = new UserBean(); user.setUserName("name1"); user.setPassword("passwd1"); em.persist(user); } 

Другая причина ошибки в том, что объект объекта не реализует интерфейс Serializable

 @Entity @Table(name = OddInstance.objectName, uniqueConstraints = @UniqueConstraint(columnNames = {"alias"})) @NamedQueries({ @NamedQuery(name=OddInstance.findByAlias, query="from OddInstance where alias = :alias"), @NamedQuery(name=OddInstance.findAll, query="from OddInstance") }) public class OddInstance implements Serializable { // ... } 
  • Spring Boot + JPA: аннотация annotations имени столбца игнорируется
  • В чем разница между @JoinColumn и mappedBy при использовании ассоциации JPA @OneToMany
  • JPA getSingleResult () или null
  • @PreUpdate и @Prepersist в спящем / JPA (с использованием сеанса)
  • Каков правильный путь для ссылки jar-файла в jpa persistence.xml в веб-приложении?
  • Установка параметра в виде списка для выражения IN
  • Предполагается, что в JPA есть один repository за столом?
  • JPA 2.0 orphanRemoval = true VS on delete Cascade
  • Нарушение спящего режима с помощью orphanRemoval
  • Указание индекса (не-уникальный ключ) с использованием JPA
  • JPA "@JoinTable" аннотация
  • Давайте будем гением компьютера.