【问题标题】:JPA Custom repository Not an entity: classJPA 自定义存储库不是实体:类
【发布时间】:2021-07-15 09:29:37
【问题描述】:

朋友。帮我解决问题。我使用弹簧 jpa。我通过使用 @Autowired 注释指定存储库来从 RestController 发出所有请求。 我知道您可以创建一个存储库类并继承 JpaRepository,但我想弄清楚如何使用我的自定义存储库。当然,如果我使用JpaRepository,那就没有错误了。

我的配置类:

package net.sunnikolay.multipledb.config;

@Configuration
    @PropertySource( { "classpath:application.properties" } )
    @EnableJpaRepositories(
        basePackages = "net.sunnikolay.multipledb.repository.ab",
        entityManagerFactoryRef = "abEntityManager",
        transactionManagerRef = "abTransactionManager"
)
public class AbHttpApiDBConfiguration {
    
    @Value( "${db.ab.datasource.hibernate.dialect}" )
    private String dialect;
    
    @Value( "${db.ab.datasource.hibernate.hbm2ddl.auto}" )
    private String hbmDdl;
    
    @Bean
    @ConfigurationProperties( prefix = "db.ab.datasource" )
    public DataSource abDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean abEntityManager() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource( abDataSource() );
        em.setPackagesToScan( "net.sunnikolay.multipledb.domain.ab" );
        
        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter( vendorAdapter );
        final HashMap<String, Object> properties = new HashMap<>();
        properties.put( "hibernate.hbm2ddl.auto", hbmDdl );
        properties.put( "hibernate.dialect", dialect );
        em.setJpaPropertyMap( properties );
        
        return em;
    }
    
    @Bean
    public PlatformTransactionManager abTransactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory( abEntityManager().getObject() );
        return transactionManager;
    }
    
}

我的实体:

package net.sunnikolay.multipledb.domain.ab;

import javax.persistence.*;

@Entity
@Table(name = "columns", schema = "invitro_report")
public class TColumn {

    @Id
    @Column(name = "report_name")
    private String reportName;
    
    @Column(name = "index")
    private int index;
    
    @Column(name = "field")
    private String field;
    
    @Column(name = "title")
    private String title;
    
    @Column(name = "description")
    private String desc;
    
    public TColumn() {
    }
    
    public String getReportName() {
        return reportName;
    }
    
    public void setReportName( String reportName ) {
        this.reportName = reportName;
    }
    
    public int getIndex() {
        return index;
    }
    
    public void setIndex( int index ) {
        this.index = index;
    }
    
    public String getField() {
        return field;
    }
    
    public void setField( String field ) {
        this.field = field;
    }
    
    public String getTitle() {
        return title;
    }
    
    public void setTitle( String title ) {
        this.title = title;
    }
    
    public String getDesc() {
        return desc;
    }
    
    public void setDesc( String desc ) {
        this.desc = desc;
    }
    
}

我的 AbRepositoryCustom:

package net.sunnikolay.multipledb.repository.ab;

@Repository
public interface AbRepositoryCustom {
    
    List<TColumn> findByName( String name );
    
}

我的 AbRepositoryCustomImpl:

package net.sunnikolay.multipledb.repository.ab;

@Repository
public class AbRepositoryCustomImpl implements AbRepositoryCustom {
    
    @PersistenceContext
    private EntityManager manager;
    
    @Override
    public List<TColumn> findByName( String name ) {
        List<TColumn> result = new ArrayList<>();
        
        try {
            CriteriaBuilder        cb   = manager.getCriteriaBuilder();
            CriteriaQuery<TColumn> cq   = cb.createQuery( TColumn.class );
            Root<TColumn>          root = cq.from( TColumn.class );
            
            Predicate[] predicates = new Predicate[ 1 ];
            predicates[ 0 ] = cb.equal( root.get( "reportName" ), name );
            
            cq.select( root ).where( predicates );
            
            TypedQuery<TColumn> query = manager.createQuery( cq );
            result = query.getResultList();
        }
        catch ( NoResultException ignore ) {}
        catch ( Exception jce ) {
            jce.printStackTrace();
        }
        
        return result;
    }
    
}

当我提出请求时,在 Root root = cq.from( TColumn.class ); 一行 "Not an entity: class net.sunnikolay.multipledb.domain.ab .TColumn 发生错误。

【问题讨论】:

  • 您有多个EntityManagerFactory 实例吗?如果是这样,你得到了错误的,如果不是,为什么要手动配置? @EnableJpaRepositories 没用,因为您没有使用 Spring Data JPA,而是在编写自己的实现。
  • @M.Deinum ,是的,我使用了多个EntityManagerFactory。我设法完成了请求,我在AbRepositoryCustomImpl 中添加了注释@PersistenceContext(UnitName = "abEntityManager")。这种方法正确吗?还是我错了?

标签: java spring hibernate spring-data-jpa


【解决方案1】:

您可以创建自定义存储库,但像这样,您必须扩展 JpaRepository

public interface AbRepositoryCustom extends JpaRepository<Store, Long> {
 List<TColumn> findByName( String name );
}

【讨论】:

  • 感谢您的回答,但这不是我需要的。我选择了自定义存储库方向,因为我计划使用复杂的查询,并且我对创建自定义存储库的方法很感兴趣
  • 你可以有这样的复杂查询 @Query("SELECT u FROM User u WHERE u.status = 1") Collection findAllActiveUsers();或像这样的原生查询 @Query(value = "SELECT * FROM USERS u WHERE u.status = 1", nativeQuery = true) Collection findAllActiveUsersNative();
猜你喜欢
  • 2019-07-28
  • 2022-01-25
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
相关资源
最近更新 更多