【问题标题】:JPA Entity is not mappedJPA 实体未映射
【发布时间】:2021-09-13 09:13:17
【问题描述】:

我有使用六边形架构的 Spring 微服务应用程序。 当尝试使用 hql 查询从我的 H2 数据库中获取数据时,我有一个异常,说我的实体未映射。我的实体是另一个具有 commons 属性的实体的子类。

package com.package.infrastructure.repository.jpa.entity.nomenclature;

import lombok.Data;

import javax.persistence.*;

@Data
@MappedSuperclass
public class NomenclatureEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length = 50)
    private String label;
}

活动

package com.package.company.infrastructure.repository.jpa.entity.nomenclature;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import javax.persistence.Entity;

@Data
@EqualsAndHashCode
@ToString
@Entity(name = "N_ACTIVITY")
public class ActivityEntity extends NomenclatureEntity {
}

存储库

package com.package.company.infrastructure.repository.jpa;

import com.package.company.infrastructure.repository.jpa.entity.nomenclature.NomenclatureEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface NomenclatureSpringDataRepository extends CrudRepository<NomenclatureEntity, Long> {
}

Spring数据实现

package com.package.company.infrastructure.repository.jpa;

import com.package.company.core.NomenclatureRepository;
import com.package.company.core.model.nomenclature.*;
import com.package.company.infrastructure.repository.jpa.entity.nomenclature.*;
import com.package.company.infrastructure.repository.jpa.mapping.nomenclature.*;
import org.mapstruct.factory.Mappers;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
import java.util.stream.Collectors;

@Transactional(readOnly = true)
public class NomenclatureRepositorySpringDataWrapper implements NomenclatureRepository {

    NomenclatureSpringDataRepository nomenclatureSpringDataRepository;

    @PersistenceContext
    private EntityManager entityManager;

    public NomenclatureRepositorySpringDataWrapper(NomenclatureSpringDataRepository nomenclatureSpringDataRepository) {
        this.nomenclatureSpringDataRepository = nomenclatureSpringDataRepository;
    }

    @Override
    public List<Activity> getAllActivity() {
        Query query = entityManager.createQuery("SELECT a FROM ActivityEntity a");
        List<ActivityEntity> activityEntities = query.getResultList();
        ActivityEntityMapper mapper = Mappers.getMapper(ActivityEntityMapper.class);
        List<Activity> activities = activityEntities.stream().map(ae->mapper.toNomenclature(ae)).collect(Collectors.toList());
        return activities;
    }
}

开始上课

package com.package;

import com.package.core.NomenclatureRepository;
import com.package.core.model.nomenclature.*;
import com.package.infrastructure.config.CompanyApplicationConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

@SpringBootApplication(exclude={SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})
@Import(value = MyApplicationConfig.class)
public class MyApplication {

    @Autowired
    private NomenclatureRepository nomenclatureRepository;

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    public CommandLineRunner init(){
        return (String... args)->{
            nomenclatureRepository.saveActivity(new Activity(1L, "Activity 1"));
            nomenclatureRepository.saveActivity(new Activity(2L, "Activity 2"));
        };
    }
}

结果

2021-07-01 10:29:08.118 ERROR 9224 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: ActivityEntity is not mapped [SELECT a FROM ActivityEntity a]] with root cause

org.hibernate.hql.internal.ast.QuerySyntaxException: ActivityEntity is not mapped
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:169) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91) ~[hibernate-core-5.4.12.Final.jar:5.4.12.Final]

【问题讨论】:

    标签: spring-boot spring-data-jpa hql hexagonal-architecture


    【解决方案1】:

    您已使用@Entity(name = "N_ACTIVITY") 上课ActivityEntity@Entity 中的 name 用于 JPA-QL 查询,如果未提供值,则默认为类名,但由于您更改了它,因此您必须确保在构建查询时使用此名称。

    因此,您的查询应按如下方式更新:

    SELECT a FROM N_ACTIVITY a
    

    或者你可以去掉名字,使用类名ActivityEntity

    【讨论】:

      【解决方案2】:

      就像@deepakchethan 说的,实体名称是用于JPA-QL 查询的,你把它改成了N_ACTIVITY,所以你应该使用:

      Query query = entityManager.createQuery("SELECT a FROM N_ACTIVITY a");
      

      另一种方法是使用@Entity定义实体,并使用@Table更改默认表名:

      @Entity
      @Table(name = "N_ACTIVITY")
      public class ActivityEntity extends NomenclatureEntity {
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-22
        • 2011-10-20
        • 2020-03-21
        • 2011-07-25
        • 2015-08-02
        相关资源
        最近更新 更多