Я определенно что-то здесь упускаю.Моя проблема заключается в следующем: я получаю следующее исключение:
java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: entity.Book[ bookId=null ]
при попытке выполнить именованный запрос, хотя EntityManager
.
У меня есть служба RESTfulориентированное на Java веб-приложение, которое содержит серию xxxFacadeREST
файлов (например, BookFacadeREST
), каждый из которых содержит службы (создание, редактирование, удаление, поиск и т. д.) для данной сущности xxx (например, Book
).Я пытаюсь получить объект, находясь внутри службы / метода создания для другого объекта (например, попытаться получить BookType
, находясь внутри BookFacadeREST.create()
).Мой обычный подход к этому заключается в использовании EntityManager
, инициализируемого моим PersistenceContext
, и выполнении именованного запроса, например:
BookType bt = em.createNamedQuery("BookType.findByTypeId", BookType.class).setParameter(....) etc etc
Однако, как уже упоминалось, я получаю IllegalStateException
при этом.Вместо этого, если я пытаюсь получить BookType
через вызов собственного FacadeREST
метода find()
, все работает.Теперь, что делает это странным, это то, что я использую именованные запросы везде без проблем.Я даже использовал один ранее в том же методе создания, чтобы получить другую сущность, и это работает.Так что, должно быть, что-то не так с настройкой Book
и BookType
(я полагаю).
public class BookFacadeREST extends AbstractFacade<Book> {
@EJB
private BookTypeFacadeREST bookTypeFacadeREST;
@PersistenceContext(unitName = "bla bla")
private EntityManager em;
@POST
public Book create(Book entity) {
// works fine
if (entity.getLibraryId() != null) {
lib = em.createNamedQuery("Library.findByLibraryId", Library.class).setParameter("libraryId", entity.getLibraryId().getLibraryId()).getSingleResult();
....
}
if (entity.getTypeId() != null) {
....
} else {
BookType defaultType = bookTypeFacadeREST.find(new Long(1L));
// For some reason retrieving the book type using em.createNamedQuery DOES NOT WORK !!!
//BookType defaultType = em.createNamedQuery("BookType.findByTypeId", BookType.class).setParameter("typeId", new Long(1L)).getSingleResult();
entity.setTypeId(defaultType);
defaultType.addBook(entity);
}
.....
return super.create(entity);
}
}
@Entity
@Multitenant(value = TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
@Table(name = "book")
@XmlRootElement
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "bookId")
private Long bookId;
@JoinColumn(name = "typeId", referencedColumnName = "typeId")
@ManyToOne(optional = false)
@NotNull
private BookType typeId;
@JoinColumn(name = "libraryId", referencedColumnName = "libraryId")
@ManyToOne(optional = false)
private Library libraryId;
.....
}
@Entity
@Multitenant(value = TABLE_PER_TENANT)
@TenantTableDiscriminator(type = SCHEMA, contextProperty = MULTITENANT_PROPERTY_DEFAULT)
@Table(name = "book_type")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "BookType.findByTypeId", query = "SELECT b FROM BookType b WHERE b.typeId = :typeId")})
public class BookType implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "typeId")
private Long typeId;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 50)
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "typeId")
private List<Book> bookList;
....
}
Почему поиск через EntityManager
не удается при вызове службы поиска (GET) для определенного BookType
идентификатора работает, с учетом , что
lib = em.createNamedQuery("Library.findByLibraryId", Library.class)....
также работает.
Спасибо всем заранее.