原因:java.lang.IllegalArgumentException:无法在此 ManagedType [] 上找到具有给定名称 [] 的属性

Posted

技术标签:

【中文标题】原因:java.lang.IllegalArgumentException:无法在此 ManagedType [] 上找到具有给定名称 [] 的属性【英文标题】:Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [] on this ManagedType [] 【发布时间】:2019-06-03 19:28:06 【问题描述】:

所以我有这个 kotlin 项目:

package com.example.demo

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.CrudRepository
import java.util.*
import javax.persistence.*

@MappedSuperclass
abstract class ContainerEntity<TData : DataEntity> 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int = 0

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.ALL], optional = false)
    lateinit var data: TData



@MappedSuperclass
abstract class DataEntity 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int = 0

    val created = Date()


@Entity
class Car : ContainerEntity<CarData>()

@Entity
class CarData : DataEntity() 
    var color = "red"


@Entity
class Apple : ContainerEntity<AppleData>()

@Entity
class AppleData : DataEntity() 
    var age = 32


/**
 * WORKS
 */

interface CarRepository : CrudRepository<Car, Int> 
    fun findByDataColor(color: String): Car?



/**
 * FAILS
 */

interface AppleRepository : CrudRepository<Apple, Int> 
    fun findByDataAge(age: Int): Apple?

得到这个异常:

Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [age] on this ManagedType [com.example.demo.DataEntity]
        at org.hibernate.metamodel.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:128) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.metamodel.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:113) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.metamodel.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:111) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.query.criteria.internal.path.SingularAttributePath.locateAttributeInternal(SingularAttributePath.java:71) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177) ~[hibernate-core-5.3.10.Final.jar:5.3.10.Final]
        at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:673) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:606) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:578) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.getTypedPath(JpaQueryCreator.java:381) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:304) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:209) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:122) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:57) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:119) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:95) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:81) ~[spring-data-commons-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:147) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:270) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:79) ~[spring-data-jpa-2.1.8.RELEASE.jar:2.1.8.RELEASE]
        ... 98 common frames omitted

有一个小演示项目:https://github.com/TomGrill/spring-hibernate-bug

根据要求:

//@MappedSuperclass
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract class ContainerEntity<TData : DataEntity> 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int = 0

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.ALL], optional = false)
    lateinit var data: TData



//@MappedSuperclass
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract class DataEntity 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Int = 0

    val created = Date()

【问题讨论】:

【参考方案1】:

您正在使用@MappedSuperclassDataEntity,但您应该使用@Inheritance

@MappedSuperclass 是告诉 JPA 所有子类必须具有继承属性的注解,但它与 JPA 继承无关。

要在 JPA 中使用继承,您必须使用 @Inheritance

定义如何将继承树存储到数据库的三种策略:SINGLE_TABLE、JOINED 和 TABLE_PER_CLASS。

SINGLE_TABLE(默认):同一张表上的所有类 JOINED:每个类的表,即使它们是抽象的 TABLE_PER_CLASS:仅限非抽象类的表

【讨论】:

不幸的是,所有组合都出现同样的错误 谢谢,我更新了 OP。我尝试了所有 3 个InheritanceTypes 恐怕你的泛型水平只有一层。因为泛型是编译时构造,所以 Spring Data 不知道您在运行时使用的是哪种类型。 ContainerEntity 和 DataEntity 的目的是什么?感觉太复杂了 好吧,我基本上是在寻找一种有回滚机制的方法。因此,容器将分配 1 个数据记录,即活动记录。所以我可以更新数据记录并设置为活动或选择一个旧的并设置为活动。可能不是我在那里采取的最佳方法。我在一个较旧的项目中没有泛型就这样做了。我的计划是让它可重复使用。可能有更好的方法来处理这个问题。目前我认为拥有一个自定义存储库是解决方案。

以上是关于原因:java.lang.IllegalArgumentException:无法在此 ManagedType [] 上找到具有给定名称 [] 的属性的主要内容,如果未能解决你的问题,请参考以下文章

[转]Linux下使用JNI的常见问题及解决方案

Spring Test DBUnit:无法从文件加载数据集

JPA 认为我正在删除一个分离的对象

普通原因与特殊原因的区别

普通原因与特殊原因的区别

rca根本原因分析法是啥意思