当前位置: 首页 > 知识库问答 >
问题:

使用MappedSuperclass和子类为Spring数据存储库进行Spring Boot自定义实现

姬飞飙
2023-03-14
@MappedSuperclass
@lombok.NoArgsConstructor
@lombok.RequiredArgsConstructor
public abstract class Animal {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @lombok.Getter
    private Long id;

    @lombok.Getter
    @lombok.NonNull
    private String name;
}
@Entity
@Table
@lombok.NoArgsConstructor
public class Cat extends Animal {

    public Cat(Integer weight, String name) {
        super(name);
        this.weight = weight;
    }

    @lombok.Getter
    private Integer weight;
}
@Entity
@Table
@lombok.NoArgsConstructor
public class Dog extends Animal {

    public Dog(Integer age, String name) {
        super(name);
        this.age = age;
    }

    @lombok.Getter
    private Integer age;
}

AnimalRepository.java

@NoRepositoryBean
public interface AnimalRepository<T extends Animal> extends JpaRepository<T, Long> {

    List<T> findAllByName(String name);
}

AnimalRepositoryImpl.java

public class AnimalRepositoryImpl<T extends Animal> {

    @Autowired
    AnimalRepository<T> animalRepository;

    public List<T> findAllBySomeLogic() {
        return animalRepository.findAll().stream().filter(animal -> !animal.getName().startsWith("Z")).collect(Collectors.toList());
    }
}

现在我可以添加所有的catrepository,它仍然工作(并且工作正确)。

@Transactional
public interface CatRepository extends AnimalRepository<Cat>, CatRepositoryCustom {
}
public interface CatRepositoryCustom {

    public List<Cat> findAllBySomeLogic();
}
public class CatRepositoryImpl extends AnimalRepositoryImpl implements CatRepositoryCustom {
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@ActiveProfiles(profiles = "test")
public class AnimalRepositoryTest {

    @After
    public void tearDown() {
        catRepository.deleteAll();
    }

    @Autowired
    private CatRepository catRepository;

    @Test
    public void shouldFindAllBySomeLogic() {
        // given
        catRepository.save(Lists.newArrayList(new Cat(2000, "Luna"), new Cat(2500, "Zoe"), new Cat(1800, "Toby")));

        // when
        List<Cat> cats = catRepository.findAllBySomeLogic();

        // then
        assertThat(cats.stream().map(c -> c.getName()).collect(Collectors.toList()), containsInAnyOrder("Luna", "Toby"));
    }

    @Test
    public void shouldFindAllByName() {
        // given
        catRepository.save(Lists.newArrayList(new Cat(2000, "Luna"), new Cat(2500, "Zoe"), new Cat(1800, "Toby")));

        // when
        List<Cat> cats = catRepository.findAllByName("Luna");

        // then
        assertThat(cats.stream().map(c -> c.getName()).collect(Collectors.toList()), containsInAnyOrder("Luna"));
    }
}

我编写它的方式主要是受到这个问题的启发(但我的情况更复杂)。

所以...主要问题。-如何为dog添加存储库(几乎与cat相同)而不获得类似nouniqueBeanDefinitionException:没有符合条件的bean类型…?我尝试了@qualifier的一些变体,但在这种情况下似乎不起作用。也可能我做得完全错了。

共有1个答案

东方俊材
2023-03-14

我至少看到一个与类的泛型定义有关的失败。类CatRepositoryImpl扩展了类AnimalRepositoryImpl而没有任何泛型类型。(请参见您文章中的以下两个代码片段)

public class CatRepositoryImpl extends AnimalRepositoryImpl implements CatRepositoryCustom {

}

public class AnimalRepositoryImpl<T extends Animal> {

}

在我看来应该看起来像。

public class CatRepositoryImpl extends AnimalRepositoryImpl<Cat> implements CatRepositoryCustom {

}

除此之外,我将避免在存储库类中做与逻辑相关的事情,并将其移动到服务级别。

 类似资料:
  • 我想使用SpringDataSolr在一个服务中访问多个/2个repo。从SpringDataSolr多核和存储库中,我知道“不幸的是,通过名称空间配置支持多核是一个开放的问题”。 你能帮我举个例子吗?我怎样才能创建自定义回购协议? 我的应用程序Context.xml有两个Solr模板定义如下: 我有以下回购协议 最后,服务如下所示: 有人能告诉我如何修改代码以实现SpringDataSolrWi

  • 我试图实现一个自定义Spring存储库。我有接口: 实施: 和“主”存储库,扩展我的自定义存储库: 我使用的是Spring Boot,根据文档: 默认情况下,Spring Boot将启用JPA存储库支持,并查看@SpringBootApplication所在的包(及其子包)。 当我运行应用程序时,出现以下错误: 组织。springframework。数据映射。PropertyReferenceEx

  • 在我的项目中有几个实体具有相同的属性(对于示例'name'),所以,有可能创建一个存储库,其中使用自定义的select(实体)?因此,我从JpaRepository扩展了我的存储库,我扩展了MyCustomJpaRepository,MyCustomJpaRepository也扩展了JpaRepository,使其能够从JpaRepository授予基本功能? TKS

  • 我发现对于减少样板非常有用,但它似乎给工作带来了麻烦。我现在试图用自定义的基类存储库扩展,而在启动时,Spring在正确实例化存储库方面遇到了问题。 我已经尝试了几个关于这个主题的变体,但是没有运气让事情成功地连线起来。我在Spring的问题跟踪器https://jira.spring.io/browse/datajpa-674上遇到了一个类似的问题,但没有关于修复的解释,只是对代码进行了重构,使

  • 使用Spring Boot应用程序。我有一个类UserService,我在其中创建了一个动态查询,根据请求参数具有多个or条件: 我有UserRepository接口,我需要执行这个查询。到目前为止,我使用了findById等JPA函数或@Query(“从事件中选择id”)。 如何将此查询从服务类传递到存储库并执行它?