"отсоединенный объект передан для сохранения ошибки" с кодом 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 явно. Удаление присвоения идентификатора исправило это.
но я не получил его, что мне придется изменить, чтобы заставить код работать?
10 ответов:
скажем, у вас есть две сущности
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);то есть, как присоединить Связанный объект перед сохранением или слиянием.
ошибка возникает из-за того, что задан идентификатор объекта. Гибернация различие между временными и отдельно стоящие объекты, а
persistработает только с временными объектами. Еслиpersistзавершает объект отсоединен (который он будет, потому что идентификатор установлен), он вернет ошибку "отсоединенный объект передан для сохранения". Вы можете найти более подробную информацию здесь и здесь.однако это относится только если указан первичный ключ автоматически сгенерированный: если поле настроено для установки всегда вручную, то ваш код работает.
удалить
user.setId(1);потому что он автоматически генерируется на БД, и продолжайте с команды сохраняются.
Я получил ответ, я использовал:
em.persist(user);я использовал слияние вместо persist:
em.merge(user);но не знаю, почему упорно не работал. : (
Если вы используете для создания
id = GenerationType.AUTOстратегии в вашей организации.заменяет
user.setId (1)byuser.setId (null), и проблема решена.
Я знаю его вид слишком поздно и пролы каждый получил ответ. Но немного больше, чтобы добавить к этому: когда GenerateType установлен, persist () на объекте, как ожидается, получит сгенерированный идентификатор.
Если пользователь уже установил значение Id, hibernate обрабатывает его как сохраненную запись и поэтому он рассматривается как отсоединенный.
если идентификатор равен null - в этой ситуации исключение нулевого указателя возникает, когда тип является AUTO или IDENTITY и т. д., Если идентификатор не генерируется из a таблица или sequece etc.
дизайн: это происходит, когда таблица имеет свойство bean в качестве первичного ключа. GenerateType должен быть установлен только тогда, когда ID создается автоматически. удалите это, и вставка должна работать с указанным пользователем идентификатором. (это плохой дизайн, чтобы иметь свойство сопоставляется с полем первичного ключа)
здесь .сохраняться() только вставить запись.Если мы используем .merge () он проверит, существует ли какая-либо запись с текущим идентификатором, если она существует, она будет обновляться, иначе она вставит новую запись.
У меня была эта проблема, и это было вызвано кэш второго уровня:
- Я сохранил сущность с помощью hibernate
- затем я удалил строку, созданную из отдельного процесса, который не взаимодействовал с кэшем второго уровня
- Я сохранил другой объект с тем же идентификатором (мои значения идентификаторов не генерируются автоматически)
следовательно, поскольку кэш не был признан недействительным, 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 { // ... }

Comments