【问题标题】:How to create repository for more than one entity?如何为多个实体创建存储库?
【发布时间】:2012-08-21 08:45:40
【问题描述】:

我正在尝试创建一个托管主题和 cmets 的简单网站。我从主题开始,并为它们创建了存储库:

package com.myProject.mvc3.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TopicRepository extends CrudRepository<Topic, Integer>{    
     public List<Topic> findAllByTopicTag(Tag currentTag);
} 

我已经在 servlet-context.xml 中定义了我的存储库的路径:

jpa:repositories base-package="com.myProject.mvc3.repository"

现在,我想将 cmets 包含在我的存储库中,但以下代码不起作用:

package com.myProject.mvc3.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CommentRepository extends CrudRepository<Comment, Integer> {
    public List<Comment> findTopicComments(Topic topic);

}

我的项目甚至没有构建。您能否给我一个建议,如何为多个实体创建存储库(Topic 类和 Comment 类使用 @Entity 声明)?

我所面对的:

  • TopicRepository类图标上有硬盘图片
  • CommentRepository类图标上有一个问号
  • 错误日志(一个巨大的):

org.springframework.beans.factory.BeanCreationException:创建名为“org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0”的bean时出错:bean初始化失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“topicController”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.epam.mvc3.service.CommentService com.epam.mvc3.controller.TopicController.commentService;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“commentService”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.epam.mvc3.repository.CommentRepository com.epam.mvc3.service.CommentService.commentRepository;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名称为“commentRepository”的 bean 时出错:FactoryBean 在创建对象时抛出异常;嵌套异常是 java.lang.IllegalArgumentException: No property find found for type class com.epam.mvc3.model.Comment org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:467) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:483) org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:358) org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:325) org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127) javax.servlet.GenericServlet.init(GenericServlet.java:160) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928) com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:84) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539) org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:298) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) java.lang.Thread.run(Thread.java:722)

【问题讨论】:

  • 不确定最后一条语句应该是什么意思,但您能否附加您面临的构建/编译器错误?

标签: spring spring-mvc spring-data-jpa


【解决方案1】:

只需在findTopicComments 中添加By,使其变为findByTopicComments。当然,这仅适用于Comment 实体具有topicComments 字段或具有topic 字段而后者又具有comments 字段的情况。

顺便说一句,Spring-data-jpa 存储库上不需要 @Repository 注释。

实际上,如果您的查询名称与 this 类中的模式 ^(find|read|get)(\\p{Upper}.*?)??By 不匹配,则会发生以下情况:

  • get、'read' 和 find 等任何前缀都不会被删除,而是会被视为要生成的 JPQL 查询的一部分。在这种情况下,你会得到一个例外: java.lang.IllegalArgumentException: No property find found for type class ...
  • 如果您的方法名称中没有任何内容可删除,那么它将被处理,就好像它之前有 findBy 前缀一样。

由于这在文档中并不清楚,我在Spring Data Commons 问题跟踪器中创建了issue

【讨论】:

  • 命名方式有什么限制吗?
  • 请参阅this 部分的Spring-data-jpa 文档。
【解决方案2】:

尝试以这种方式编写您的存储库:

@Repository
public interface TopicRepository extends JpaRepository<Topic, Integer> >{    

     @Query("select topic from Topic topic where topic.topicTag.id=?1")
     public List<Topic> findAllByTopicTag(int topicTagId);
} 

@Repository
public interface CommentRepository extends JpaRepository<Comment, Integer> {

    @Query("select comment from Comment comment where comment.topic.id=?1")
    public List<Comment> findTopicComments(int topicId);
}

在本例中,我将实体的 id 指定为搜索条件,因为它们通常用作外键。如果需要,您可以轻松添加其他搜索条件。

有关 Spring Data 中查询方法的更多详细信息,您可以在 reference documentation 中找到。

更新

关于你的错误堆栈跟踪——我认为这个错误意味着你没有在persistent.xml 中指定你的类。

还有一种方法可以不在persistent.xml 中指定所有类-> 查看herehere 了解详细信息。

此外,如果您使用完整的 java 配置,您还可以使用 Spring 轻松配置您的 JPA 项目而无需 persistent.xml 文件。例如:

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    LocalContainerEntityManagerFactoryBean factoryBean = 
            new LocalContainerEntityManagerFactoryBean();

    factoryBean.setDataSource(dataSource());
    factoryBean.setPackagesToScan(new String[] {"com.dimasco.springjpa.domain"});

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setShowSql(true);
    //vendorAdapter.setGenerateDdl(generateDdl)

    factoryBean.setJpaVendorAdapter(vendorAdapter);

    Properties additionalProperties = new Properties();
    additionalProperties.put("hibernate.hbm2ddl.auto", "update");

    factoryBean.setJpaProperties(additionalProperties);


    return factoryBean;
}

正如您在此示例中所见,我只是定义了要扫描的包。

【讨论】:

    猜你喜欢
    • 2016-02-01
    • 1970-01-01
    • 2020-03-06
    • 2015-05-23
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    相关资源
    最近更新 更多