10

我有一个实体Ride,它嵌入了一个可嵌入的“实体” RouteRoute有一个 List 属性towns与 ManyToMany 关系,所以它有 fetchtype LAZY (我不想使用 EAGER)。所以我想为实体Ride定义一个 NamedEntityGraph ,以加载一个带有实例化 List of towns的Route的Ride对象。但是当我部署我的战争时,我得到了这个例外:

java.lang.IllegalArgumentException:属性 [route] 不是托管类型

@Entity
@NamedQueries({
@NamedQuery(name = "Ride.findAll", query = "SELECT m FROM Ride m")})
@NamedEntityGraphs({
@NamedEntityGraph(
        name = "rideWithInstanciatedRoute",
        attributeNodes = {
            @NamedAttributeNode(value = "route", subgraph = "routeWithTowns")
        },
        subgraphs = {
            @NamedSubgraph(
                    name = "routeWithTowns",
                    attributeNodes = {
                        @NamedAttributeNode("towns")
                    }
            )
        }
    )
})
public class Ride implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Embedded
    private Route route;

    // some getter and setter
}

路线

@Embeddable
public class Route implements Serializable {
    private static final long serialVersionUID = 1L;

    @ManyToMany
    private List<Town> towns;

    // some getter and setter
}
4

1 回答 1

10

查看 Hibernate 对org.hibernate.jpa.graph.internal.AttributeNodeImpl的实现,我们得出的结论@NamedAttributeNode不能是:

  • 简单类型(Java 原语及其包装器、字符串、枚举、时间,...)
  • 可嵌入(用 注释@Embedded
  • 元素集合(用 注释@ElementCollection
if (attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.BASIC || 
    attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED ) {
    throw new IllegalArgumentException(
        String.format("Attribute [%s] is not of managed type", getAttributeName())
    );
}

我在 JPA 2.1 规范中没有发现类似的限制,因此这可能是 Hibernate 的缺点。


在您的特定情况下,问题是@NamedEntityGraph指的Route是可嵌入的类,因此它在实体图中的使用似乎被 Hibernate 禁止(不幸的是)。

为了使其工作,您需要稍微更改您的实体模型。我脑海中浮现的几个例子:

  • 定义Route为实体

  • 删除Route并将其towns字段移动到Ride实体中(简化实体模型)

  • route字段从实体中移动,将地图的地图添加到Ride实体:TownroutedTownsRide

     @Entity
     public class Ride implements Serializable {
         ...
         @ManyToMany(mappedBy = "rides")
         private Map<Route, Town> routedTowns;
         ...
     }
    
     @Entity
     public class Town implements Serializable {
         ...
         @ManyToMany
         private List<Ride> rides;
         @Embeddable
         private Route route;
         ...
     }
    

当然,实体图可能需要相应的更改。

于 2014-12-18T21:32:00.867 回答