如何为多个实体创建存储库?

时间:2012-08-26 17:16:09

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

我正在尝试创建一个简单的网站,其中包含主题和评论。我已经开始讨论主题,并为他们创建了存储库:

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"

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

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);

}

我的项目甚至没有建立。您能否给我一个建议,如何为多个实体创建存储库(主题类和注释类是用 @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:无法自动装配字段:private com.epam.mvc3.service.CommentService com.epam.mvc3.controller.TopicController.commentService;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'commentService'的bean时出错:注入自动连接的依赖项失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.epam.mvc3.repository.CommentRepository com.epam.mvc3.service.CommentService.commentRepository;嵌套异常是org.springframework.beans.factory.BeanCreationException:创建名为'commentRepository'的bean时出错:FactoryBean在创建对象时抛出异常;嵌套异常是java.lang.IllegalArgumentException:找不到类型类com.epam.mvc3.model.Comment的属性find     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)

2 个答案:

答案 0 :(得分:2)

只需在By中添加findTopicComments即可成为findByTopicComments。当然,只有Comment实体具有topicComments字段或topic字段,而comments字段具有@Repository字段时才会有效。

顺便说一下,Spring-data-jpa存储库中不需要^(find|read|get)(\\p{Upper}.*?)??By注释。

实际上,如果您的查询名称与this类中的模式get不匹配,则会发生以下情况:

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

由于我在文档中不明确,因此我在{{1}}问题跟踪器中创建了issue

答案 1 :(得分:1)

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

@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中指定所有类 - &gt;有关详细信息,请查看herehere

如果使用完整的java配置,使用Spring,您可以轻松配置没有persistent.xml文件的JPA项目。例如:

@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;
}

正如您在本示例中所看到的,我只需定义要扫描的包。

相关问题