简体   繁体   中英

spring data repository failed to save entity with idClass

I have a simple project using spring data jpa with hibernate implementation. There is an entity with composite id, which I mapped it with id-class in xml. I defined my entity like this:

public class MyEntity {
    private long idA;
    private String idB;
    private String idC;

    public MyEntity() {
        super();
    }

    public MyEntity(long anIdA, String anIdB, String anIdC) {
        super();
        this.idA = anIdA;
        this.idB = anIdB;
        this.idC = anIdC;
    }

    public long getIdA() {
        return idA;
    }

    public String getIdB() {
        return idB;
    }

    public String getIdC() {
        return idC;
    }

    @Override
    public String toString() {
        return "Entity [idA=" + idA + ", idB=" + idB
                + ", idC=" + idC + "]";
    }
}

I defined idClass like this:

public class MyEntityId implements Serializable {
    private static final long serialVersionUID = 9073138829628574603L;

    private long idA;
    private String idB;
    private String idC;

    public MyEntityId() {
    }

    public MyEntityId(long anIdA, String anIdB, String anIdC) {
        this.idA = anIdA;
        this.idB = anIdB;
        this.idC = anIdC;
    }

    public long getIdA() {
        return idA;
    }

    public String getIdB() {
        return idB;
    }

    public String getIdC() {
        return idC;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj != null && obj instanceof MyEntityId) {
            MyEntityId uk = (MyEntityId) obj;
            return this.idA == uk.getIdA()
                    && this.idB != null ?
                            this.idB.equals(uk.getIdB())
                            : uk.getIdB() == null
                    && this.idC != null ?
                            this.idC.equals(uk.getIdC())
                            : uk.getIdC() == null;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(idA, idB, idC);
    }

}

My repository is this:

public interface MyEntityJpaRepository extends
        JpaRepository<MyEntity, MyEntityId> {
}

And the orm.xml

<entity class="myProject.domain.MyEntity" name="MyEntity"
    metadata-complete="true" access="FIELD">
    <table name="tb_myentity" />
    <id-class class="myproject.persistance.MyEntityId" />
    <attributes>
        <id name="idA">
            <column name="id_a" />
        </id>
        <id name="idB">
            <column name="id_b" />
        </id>
        <id name="idC">
            <column name="id_c" />
        </id>
    </attributes>
</entity>

Now is the problem: MyEntityJpaRepository.exists(aMyEntityIdInstance) is worked well, but MyEntityJpaRepository.save(aMyEntityInstance) throws this exeption:

org.springframework.dao.InvalidDataAccessApiUsageException: Class must not be null; nested exception is java.lang.IllegalArgumentException: Class must not be null

by SimpleJpaRepository.save

I found spring Data seemed to fail to get an ID. What have I done wrong or what did I missed? Any body can help?

Edit: This is the code in which the exception happenned.

    @Autowired
    private MyEntityJpaRepository myProxyRepository;
   ....
    public void append(long idA, String idB, String idC) {
        assertNotNull(idB);
        assertNotNull(idC);
        myProxyRepository.save(new MyEntity(idA, idB, idC)); //throw exception
    }

Here is the exception stack:

Caused by: java.lang.IllegalArgumentException: Class must not be null
at org.springframework.util.Assert.notNull(Assert.java:134)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:97)
at org.springframework.beans.AbstractNestablePropertyAccessor.<init>(AbstractNestablePropertyAccessor.java:140)
at org.springframework.beans.BeanWrapperImpl.<init>(BeanWrapperImpl.java:109)
at org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.<init>(DirectFieldAccessFallbackBeanWrapper.java:39)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdentifierDerivingDirectFieldAccessFallbackBeanWrapper.<init>(JpaMetamodelEntityInformation.java:314)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.getId(JpaMetamodelEntityInformation.java:152)
at org.springframework.data.repository.core.support.AbstractEntityInformation.isNew(AbstractEntityInformation.java:51)
at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation.isNew(JpaMetamodelEntityInformation.java:227)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:507)
at sun.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:520)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:505)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)

Well, it's a defect of spring-data-jpa, which was fixed in 1.11.11.snapshot. Before the release version was distributed, I have to add an @IdClass annotation on the entity class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM