Получение "java.lang.IllegalArgumentException" на сопоставлении JPA двунаправленный - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть простое двунаправленное отношение сущностей Person <-> PersonHistory, со следующими сущностями JPA с классом «Deletable», содержащим переменные аудита и переменную @Id.

@Entity
@Table(name = "person")
public class Person extends Deletable {
    @Column(name = "first_name", columnDefinition = "varchar(36)")
    private String firstname;

    @Column(name = "last_name", columnDefinition = "varchar(36)")
    private String lastname;

    @Column(name = "salary", columnDefinition = "DECIMAL(13,2)")
    private BigDecimal salary;

    @OneToMany(mappedBy = "person", targetEntity = PersonHistory.class, cascade = {CascadeType.ALL}, orphanRemoval = true)
    private List<PersonHistory> personHistory;
}

@Entity
@Table(name="person_history")
public class PersonHistory extends Deletable{
    @Column(name="company", columnDefinition = "varchar(36)")
    private String company;
    @Column(name="experience", columnDefinition = "tinyint")
    private Integer experience;

    @Id
    @ManyToOne(targetEntity = Person.class,cascade= CascadeType.ALL)
    @JoinColumn(foreignKey = @ForeignKey(name = "fk_person_history_person"), name = "person_id", referencedColumnName="id")
    private Person person;

Структура таблицы с отношением ссылочный ключ: -

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<table border="1" style="border-collapse:collapse">
<tr><th>Field</th><th>Type</th><th>Null</th><th>Key</th><th>Default</th><th>Extra</th></tr>
<tr><td>id</td><td>bigint(20)</td><td>NO</td><td>PRI</td><td>NULL</td><td>auto_increment</td></tr>
<tr><td>created_at</td><td>bigint(20)</td><td>NO</td><td></td><td>NULL</td><td></td></tr>
<tr><td>updated_at</td><td>bigint(20)</td><td>NO</td><td></td><td>NULL</td><td></td></tr>
<tr><td>first_name</td><td>varchar(36)</td><td>YES</td><td></td><td>NULL</td><td></td></tr>
<tr><td>last_name</td><td>varchar(36)</td><td>YES</td><td></td><td>NULL</td><td></td></tr>
<tr><td>salary</td><td>decimal(13,2)</td><td>YES</td><td></td><td>NULL</td><td></td></tr>
<tr><td>deleted</td><td>tinyint(4)</td><td>NO</td><td></td><td>0</td><td></td></tr></table>
</body>
</html>

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<table border="1" style="border-collapse:collapse">
<tr><th>Field</th><th>Type</th><th>Null</th><th>Key</th><th>Default</th><th>Extra</th></tr>
<tr><td>id</td><td>bigint(20)</td><td>NO</td><td>PRI</td><td>NULL</td><td>auto_increment</td></tr>
<tr><td>created_at</td><td>bigint(20)</td><td>NO</td><td></td><td>NULL</td><td></td></tr>
<tr><td>updated_at</td><td>bigint(20)</td><td>NO</td><td></td><td>NULL</td><td></td></tr>
<tr><td>company</td><td>varchar(36)</td><td>YES</td><td></td><td>NULL</td><td></td></tr>
<tr><td>experience</td><td>tinyint(4)</td><td>YES</td><td></td><td>NULL</td><td></td></tr>
<tr><td>person_id</td><td>bigint(20)</td><td>NO</td><td>MUL</td><td>NULL</td><td></td></tr>
<tr><td>deleted</td><td>tinyint(4)</td><td>NO</td><td></td><td>0</td><td></td></tr></table>
</body>
</html>

но получаю сообщение об ошибке, говорящее, что

Caused by: java.lang.IllegalArgumentException: This class [class com.experiments.javaxpersistence.entity.PersonHistory] does not define an IdClass
at org.hibernate.metamodel.internal.AbstractIdentifiableType.getIdClassAttributes(AbstractIdentifiableType.java:183) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:257) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.<init>(JpaMetamodelEntityInformation.java:88) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getEntityInformation(JpaEntityInformationSupport.java:66) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:201) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:151) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:134) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:65) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:305) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.util.Lazy.getNullable(Lazy.java:211) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.util.Lazy.get(Lazy.java:94) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:121) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
... 41 common frames omitted

Я все еще не использую составную структуру ключей, получаю ошибку, и если я изменил ее на составнойструктура ключа я получаю следующее исключение: -

Caused by: org.hibernate.HibernateException: No part of a composite identifier may be null
at org.hibernate.tuple.entity.AbstractEntityTuplizer$IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:365) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:219) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5025) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4725) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:294) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:513) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:102) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:828) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:795) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:298) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:490) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:415) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:216) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:523) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:455) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:418) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:216) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:149) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:459) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:295) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:196) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:127) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:62) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:804) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789) ~[hibernate-core-5.3.11.Final.jar:5.3.11.Final]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:309) ~[spring-orm-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at com.sun.proxy.$Proxy87.persist(Unknown Source) ~[na:na]
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:535) ~[spring-data-jpa-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.10.RELEASE.jar:2.1.10.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
... 19 common frames omitted

Более того, следующие зависимости, я использую

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-hikaricp</artifactId>
    </dependency>
    <!-- mariadb connector -->
    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <version>${mariadb-java-client.version}</version>
    </dependency>
    <!-- connection pool implementation -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>

с возможностью удаления как: -

    @MappedSuperclass
    public class Deletable extends Auditable {
        @Column(name = "deleted", columnDefinition = "tinyint")
        private Integer deleted;
}

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
public class Auditable extends Identifiable {

    /**
     * Created UNIX time
     */
    @Column(name = "created_at", columnDefinition = "bigint", nullable = false)
    @CreatedDate
    private Long createdAt;

    /**
     * Last updated UNIX time
     */
    @LastModifiedDate
    @Column(name = "updated_at", columnDefinition = "bigint", nullable = false)
    private Long updatedAt;
}

@MappedSuperclass
public class Identifiable implements Serializable {

    /**
     * Serializable identifier
     */
    private static final long serialVersionUID = -5779695865916191496L;

    /**
     * The primary key of a table
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

1 Ответ

0 голосов
/ 30 сентября 2019

Я ошибочно добавил @Id к объекту "Person" в классе "PersonHistory", после удаления он работал без сбоев.

...