"Отключенный объект, переданный для сохранения ошибки" с кодом 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. Исправлено удаление идентификатора.
Но я не понял, что мне нужно изменить, чтобы заставить код работать?
Ответы
Ответ 1
![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<Photo> photos = new HashSet<Photo>();
}
Класс фотографий
@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);
Вот как присоединить связанный объект до того, как вы будете продолжать или сливаться.
Ответ 2
Ошибка возникает из-за того, что установлен идентификатор объекта. Спящий режим различает переходные и отдельные объекты, а persist
работает только с переходными объектами. Если persist
завершает удаление объекта (что будет связано с тем, что идентификатор установлен), он вернет ошибку "отсоединенный объект, прошедший для сохранения". Вы можете найти более подробную информацию здесь и здесь.
Однако это применимо только в том случае, если вы указали первичный ключ, который должен быть автоматически сгенерирован: если поле настроено всегда на ручной настройку, тогда ваш код работает.
Ответ 3
удалить
user.setId(1);
поскольку он автоматически генерируется на БД,
и продолжайте с помощью команды persist.
Ответ 4
Я получил ответ, я использовал:
em.persist(user);
Я использовал слияние вместо persist:
em.merge(user);
Но не знаю, почему упорство не сработало.: (
Ответ 5
если вы используете для создания стратегии id = GenerationType.AUTO
в своей сущности.
Заменяет user.setId (1)
на user.setId (null)
, и проблема решена.
Ответ 6
Я знаю, что он слишком поздно и уверен, что каждый получил ответ. Но немного больше, чтобы добавить к этому: когда установлен GenerateType, persist() на объекте должен получить генерируемый идентификатор.
Если уже установлено значение, заданное пользователем Id, hibernate рассматривает его как сохраненную запись и поэтому обрабатывается как отсоединенный.
если id равен null - в этой ситуации исключение нулевого указателя возникает, когда тип AUTO или IDENTITY и т.д., если идентификатор не генерируется из таблицы или секировки и т.д.
design: это происходит, когда таблица имеет свойство bean в качестве первичного ключа.
GenerateType должен быть установлен только тогда, когда идентификатор автогенерируется.
удалите это, и вставка должна работать с указанным пользователем идентификатором.
(это плохой дизайн, чтобы иметь свойство, отображаемое в поле первичного ключа)
Ответ 7
Здесь .perist() будет только вставлять запись. Если мы используем .merge(), он проверит, существует ли какая-либо запись с текущим идентификатором. Если она существует, она обновится, иначе она будет вставлять новую запись.
Ответ 8
У меня была эта проблема, и она была вызвана кешем второго уровня:
- Я сохранял объект, использующий hibernate
- Затем я удалил строку, созданную из отдельного процесса, который не взаимодействовал с кешем второго уровня
- Я сохранял другой объект с тем же идентификатором (мои значения идентификатора не сгенерированы автоматически)
Следовательно, поскольку кеш не был аннулирован, hibernate предположил, что он имеет дело с отдельным экземпляром того же объекта.
Ответ 9
Если вы установите id в своей базе данных как первичный ключ и автоинкремент, то эта строка кода неверна:
user.setId(1);
Попробуйте следующее:
public static void main(String[] args){
UserBean user = new UserBean();
user.setUserName("name1");
user.setPassword("passwd1");
em.persist(user);
}
Ответ 10
Другая причина ошибки в том, что объект объекта не реализует интерфейс 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 {
// ...
}