Составной ключ JPA, в котором ManyToOne получает исключение org.hibernate.PropertyAccessException: не удалось установитьJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Составной ключ JPA, в котором ManyToOne получает исключение org.hibernate.PropertyAccessException: не удалось установить

Сообщение Anonymous »

У меня есть составной ключ ContractServiceLocationPK, состоящий из трех идентификаторов (

Код: Выделить всё

contractId
, locationId, serviceId) типа long во встраиваемом классе. Класс ContractServiceLocation, использующий этот составной ключ, сопоставляет эти идентификаторы с помощью аннотации @MapsId с их объектами. Вот как это выглядит (удалены методы установки/получания и ненужные свойства):

Контракт

Код: Выделить всё

@Entity
@Table(name = "Contract")
public class Contract implements Serializable {

public Contract() {
}

@Id
@GeneratedValue
private long id;
@OneToMany(mappedBy = "contract", cascade = CascadeType.ALL, fetch= FetchType.EAGER)
Collection contractServiceLocation;
}
ContractServiceLocationPK

Код: Выделить всё

@Embeddable
public class ContractServiceLocationPK implements Serializable {

private long contractId;
private long locationId;
private long serviceId;
}
< /code>

ContractServicelocation < /p>

@Entity
@Table(name="Contract_Service_Location")
public class ContractServiceLocation implements Serializable {

@EmbeddedId
ContractServiceLocationPK id;

@ManyToOne(cascade = CascadeType.ALL)
@MapsId("contractId")
Contract contract;

@ManyToOne(cascade = CascadeType.ALL)
@MapsId("locationId")
Location location;

@ManyToOne(cascade = CascadeType.ALL)
@MapsId("serviceId")
Service service;

BigDecimal price;
}
< /code>

При попытке сохранить объект типа ContractServicelocation каким -либо образом (напрямую или через контракт) я получаю: < /p>

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.test.model.ContractServiceLocationPK.contractId
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
at com.test.MainTest.main(MainTest.java:139)
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.test.model.ContractServiceLocationPK.contractId
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:134)
at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:441)
at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:121)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
... 1 more
Caused by: java.lang.NullPointerException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
at sun.reflect.UnsafeLongFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:122)
... 12 more
Я предполагаю, что JPA/Hibernate ожидает объект Contract вместо длинной переменной, но если я изменю переменные во встраиваемом объекте с long на их тип, я получу тип идентификатора, сопоставленного отношением «контракт», не соответствует классу первичного ключа целевой сущности.. Если я попытаюсь использовать класс id вместо встраиваемого, затем сопоставленного в сопоставлении OneToMany контракта, я получу В атрибуте «contractServiceLocation» атрибут «сопоставленный» «контракт» имеет недопустимый тип сопоставления для этой связи.. Что мне следует сделать, чтобы создать составной ключ с несколькими сопоставлениями ManyToOne?

РЕДАКТИРОВАТЬ: Добавлен фрагмент, в котором я пытаюсь сохранить предметы:

Код: Выделить всё

    Service service = new Service();
// Set all service properties
Contract contract = new Contract();
// Set all contract properties
Location location = new Location();
// Set all location properties
ContractServiceLocation csl = new ContractServiceLocation();
csl.setContract(contract);
csl.setLocation(location);
csl.setService(service);
Collection cslItems = new ArrayList();
cslItems.add(csl);

em.getTransaction().begin();
em.persist(location);
em.persist(service);
em.persist(csl);
em.persist(contract);
em.getTransaction().commit();
Причина, по которой это выглядит так, а не в каком-то DAO, заключается в том, что я сначала создаю базу данных и тестирую элементы, прежде чем приступить к разработке остальной части app.

РЕДАКТИРОВАНИЕ 2: Я переписал свои модели, и теперь все работает, за исключением Eclipse, я получаю постоянную ошибку. Вот как все выглядит на данный момент:

Контракт — без изменений (кроме удаления загрузки Eager)

ContractServiceLocationPK — Теперь это класс ID

Код: Выделить всё

public class ContractServiceLocationPK implements Serializable {

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "contract_id")
private Contract contract;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "location_id")
private Location location;
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "service_id")
private Service service;

//getters and setters
//overridden equals() and hashCode()
}
< /code>

ContractServicelocation < /p>

@Entity
@Table(name="Contract_Service_Location")
@IdClass(ContractServiceLocationPK.class)
public class ContractServiceLocation implements Serializable {

@Id
Contract contract;

@Id
Location location;

@Id
Service service;

BigDecimal price;
//getters and setters
//overridden equals() and hashCode()
}
< /code>

Это, кажется, работает правильно. Он создает композитный ключ и поддерживает взаимосвязь со всеми составными свойствами. Однако есть что -то странное. В контракте Eclipse Marks MapedBy 
на сборе @onetomany для сбора ContractServiceLocation с сообщением об ошибке в атрибуте «ContractServiceLocation», «Сопоставлен по« атрибуту »контракта» имеет неверный тип картирования Для этого отношения. . Я предполагаю, что это связано с тем, что в договоре свойство, определенное в ContractServicelocation , нет аннотации @manytoone , но это определено в составном классе. Я наткнулся на «не совпадающую JPA, но работал с Hibernate» ловушки или что здесь происходит?

Подробнее здесь: https://stackoverflow.com/questions/237 ... sexception
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»