Spring Data JPA 中的通用存储库出现问题

wMa*_*odd 0 java hibernate spring-data spring-data-jpa

我正在尝试使用 Spring Data JPA 中的通用存储库执行一些基本的数据库操作。但是,我不断遇到 IllegalArgumentException“不是托管类型:”+我的参数扩展的任何类/接口。

通用存储库.java

@Transactional
public interface GenericRepository<T> extends PagingAndSortingRepository<T, Integer> {

  @Query("SELECT g "
          + "FROM " + "#{#entityName}" + " g "
          + "WHERE g.#{#entityName}Id = ?1"
         )
  public T findById(int Id);
Run Code Online (Sandbox Code Playgroud)

例如,上面的内容抱怨类 Object,而使用 GenericRepository(我试图使用的标记接口)则会抱怨接口 DatabaseDerived 不是托管类型。

我只是在我的大部分设置中使用 @SpringBootApplication ,而我能够找到的这个问题的答案要么在我的情况下肯定不起作用,要么我似乎不知道如何将它们应用到我的应用程序中。设置或者我只是不明白它们。如果有人能给我指出一个有用的教程(在 Google 上找不到)或引导我完成如何在我的设置中使用它,我将不胜感激。

应用程序.java

@SpringBootApplication
@ComponentScan("radius.hibernate")
public class Application {

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(Application.class, args);        
    }

}
Run Code Online (Sandbox Code Playgroud)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>annonymized</groupId>
    <artifactId>radius.hibernate</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-hibernate4</artifactId>
            <version>2.6.2</version>
        </dependency>

        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>0.9.10</version>
        </dependency>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>

    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>    

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
Run Code Online (Sandbox Code Playgroud)

调节器.java

/**
 * Adjuster generated by hbm2java
 */
@Entity(name = "adjuster")
@Table(name = "Adjuster", schema = "dbo", catalog = "annonymized")
public class Adjuster implements java.io.Serializable, DatabaseDerived {

    private int adjusterId;
    private EagleUsers eagleUsersBySupervisorId;
    private EagleUsers eagleUsersByUserId;
    private boolean isW2;
    private boolean autoAssign;
    private boolean active;
    private boolean isRecordDeleted;
    private Set<AdjusterSoftware> adjusterSoftwares = new HashSet<AdjusterSoftware>(0);
    private Set<BankInvoiceCorrection> bankInvoiceCorrectionsForOldAdjusterId = new HashSet<BankInvoiceCorrection>(0);
    private Set<BankAdjuster> bankAdjusters = new HashSet<BankAdjuster>(0);
    private Set<SymbilityAdjuster> symbilityAdjusters = new HashSet<SymbilityAdjuster>(0);
    private AdjusterCompensation adjusterCompensation;
    private AdjusterContact adjusterContact;
    private Set<AdjusterClaimType> adjusterClaimTypes = new HashSet<AdjusterClaimType>(0);
    private Set<AdjusterClientExclude> adjusterClientExcludes = new HashSet<AdjusterClientExclude>(0);
    private Set<AdjusterEquipment> adjusterEquipments = new HashSet<AdjusterEquipment>(0);
    private Set<ClaimAdjuster> claimAdjusters = new HashSet<ClaimAdjuster>(0);
    private Set<ClaimReport> claimReports = new HashSet<ClaimReport>(0);
    private Set<Invoice> invoices = new HashSet<Invoice>(0);
    private Set<LicenseAdjuster> licenseAdjusters = new HashSet<LicenseAdjuster>(0);
    private Set<AdjusterClientContactExclude> adjusterClientContactExcludes = new HashSet<AdjusterClientContactExclude>(
            0);
    private Set<BankInvoiceCorrection> bankInvoiceCorrectionsForNewAdjusterId = new HashSet<BankInvoiceCorrection>(0);
    private AdjusterAutoAssign adjusterAutoAssign;
    private Set<AdjusterLossType> adjusterLossTypes = new HashSet<AdjusterLossType>(0);

    public Adjuster() {
    }

    public Adjuster(int adjusterId, EagleUsers eagleUsersBySupervisorId, EagleUsers eagleUsersByUserId, boolean isW2,
            boolean autoAssign, boolean active, boolean isRecordDeleted) {
        this.adjusterId = adjusterId;
        this.eagleUsersBySupervisorId = eagleUsersBySupervisorId;
        this.eagleUsersByUserId = eagleUsersByUserId;
        this.isW2 = isW2;
        this.autoAssign = autoAssign;
        this.active = active;
        this.isRecordDeleted = isRecordDeleted;
    }

    public Adjuster(int adjusterId, EagleUsers eagleUsersBySupervisorId, EagleUsers eagleUsersByUserId, boolean isW2,
            boolean autoAssign, boolean active, boolean isRecordDeleted, Set<AdjusterSoftware> adjusterSoftwares,
            Set<BankInvoiceCorrection> bankInvoiceCorrectionsForOldAdjusterId, Set<BankAdjuster> bankAdjusters,
            Set<SymbilityAdjuster> symbilityAdjusters, AdjusterCompensation adjusterCompensation,
            AdjusterContact adjusterContact, Set<AdjusterClaimType> adjusterClaimTypes,
            Set<AdjusterClientExclude> adjusterClientExcludes, Set<AdjusterEquipment> adjusterEquipments,
            Set<ClaimAdjuster> claimAdjusters, Set<ClaimReport> claimReports, Set<Invoice> invoices,
            Set<LicenseAdjuster> licenseAdjusters, Set<AdjusterClientContactExclude> adjusterClientContactExcludes,
            Set<BankInvoiceCorrection> bankInvoiceCorrectionsForNewAdjusterId, AdjusterAutoAssign adjusterAutoAssign,
            Set<AdjusterLossType> adjusterLossTypes) {
        this.adjusterId = adjusterId;
        this.eagleUsersBySupervisorId = eagleUsersBySupervisorId;
        this.eagleUsersByUserId = eagleUsersByUserId;
        this.isW2 = isW2;
        this.autoAssign = autoAssign;
        this.active = active;
        this.isRecordDeleted = isRecordDeleted;
        this.adjusterSoftwares = adjusterSoftwares;
        this.bankInvoiceCorrectionsForOldAdjusterId = bankInvoiceCorrectionsForOldAdjusterId;
        this.bankAdjusters = bankAdjusters;
        this.symbilityAdjusters = symbilityAdjusters;
        this.adjusterCompensation = adjusterCompensation;
        this.adjusterContact = adjusterContact;
        this.adjusterClaimTypes = adjusterClaimTypes;
        this.adjusterClientExcludes = adjusterClientExcludes;
        this.adjusterEquipments = adjusterEquipments;
        this.claimAdjusters = claimAdjusters;
        this.claimReports = claimReports;
        this.invoices = invoices;
        this.licenseAdjusters = licenseAdjusters;
        this.adjusterClientContactExcludes = adjusterClientContactExcludes;
        this.bankInvoiceCorrectionsForNewAdjusterId = bankInvoiceCorrectionsForNewAdjusterId;
        this.adjusterAutoAssign = adjusterAutoAssign;
        this.adjusterLossTypes = adjusterLossTypes;
    }

    @Id

    @Column(name = "AdjusterId", unique = true, nullable = false)
    public int getAdjusterId() {
        return this.adjusterId;
    }

    public void setAdjusterId(int adjusterId) {
        this.adjusterId = adjusterId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "SupervisorId", nullable = false)
    public EagleUsers getEagleUsersBySupervisorId() {
        return this.eagleUsersBySupervisorId;
    }

    public void setEagleUsersBySupervisorId(EagleUsers eagleUsersBySupervisorId) {
        this.eagleUsersBySupervisorId = eagleUsersBySupervisorId;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "UserId", nullable = false)
    public EagleUsers getEagleUsersByUserId() {
        return this.eagleUsersByUserId;
    }

    public void setEagleUsersByUserId(EagleUsers eagleUsersByUserId) {
        this.eagleUsersByUserId = eagleUsersByUserId;
    }

    @Column(name = "IsW2", nullable = false)
    public boolean isIsW2() {
        return this.isW2;
    }

    public void setIsW2(boolean isW2) {
        this.isW2 = isW2;
    }

    @Column(name = "AutoAssign", nullable = false)
    public boolean isAutoAssign() {
        return this.autoAssign;
    }

    public void setAutoAssign(boolean autoAssign) {
        this.autoAssign = autoAssign;
    }

    @Column(name = "Active", nullable = false)
    public boolean isActive() {
        return this.active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    @Column(name = "IsRecordDeleted", nullable = false)
    public boolean isIsRecordDeleted() {
        return this.isRecordDeleted;
    }

    public void setIsRecordDeleted(boolean isRecordDeleted) {
        this.isRecordDeleted = isRecordDeleted;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterSoftware> getAdjusterSoftwares() {
        return this.adjusterSoftwares;
    }

    public void setAdjusterSoftwares(Set<AdjusterSoftware> adjusterSoftwares) {
        this.adjusterSoftwares = adjusterSoftwares;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjusterByOldAdjusterId")
    public Set<BankInvoiceCorrection> getBankInvoiceCorrectionsForOldAdjusterId() {
        return this.bankInvoiceCorrectionsForOldAdjusterId;
    }

    public void setBankInvoiceCorrectionsForOldAdjusterId(
            Set<BankInvoiceCorrection> bankInvoiceCorrectionsForOldAdjusterId) {
        this.bankInvoiceCorrectionsForOldAdjusterId = bankInvoiceCorrectionsForOldAdjusterId;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<BankAdjuster> getBankAdjusters() {
        return this.bankAdjusters;
    }

    public void setBankAdjusters(Set<BankAdjuster> bankAdjusters) {
        this.bankAdjusters = bankAdjusters;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<SymbilityAdjuster> getSymbilityAdjusters() {
        return this.symbilityAdjusters;
    }

    public void setSymbilityAdjusters(Set<SymbilityAdjuster> symbilityAdjusters) {
        this.symbilityAdjusters = symbilityAdjusters;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "adjuster", optional = false)
    public AdjusterCompensation getAdjusterCompensation() {
        return this.adjusterCompensation;
    }

    public void setAdjusterCompensation(AdjusterCompensation adjusterCompensation) {
        this.adjusterCompensation = adjusterCompensation;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "adjuster")
    public AdjusterContact getAdjusterContact() {
        return this.adjusterContact;
    }

    public void setAdjusterContact(AdjusterContact adjusterContact) {
        this.adjusterContact = adjusterContact;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterClaimType> getAdjusterClaimTypes() {
        return this.adjusterClaimTypes;
    }

    public void setAdjusterClaimTypes(Set<AdjusterClaimType> adjusterClaimTypes) {
        this.adjusterClaimTypes = adjusterClaimTypes;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterClientExclude> getAdjusterClientExcludes() {
        return this.adjusterClientExcludes;
    }

    public void setAdjusterClientExcludes(Set<AdjusterClientExclude> adjusterClientExcludes) {
        this.adjusterClientExcludes = adjusterClientExcludes;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterEquipment> getAdjusterEquipments() {
        return this.adjusterEquipments;
    }

    public void setAdjusterEquipments(Set<AdjusterEquipment> adjusterEquipments) {
        this.adjusterEquipments = adjusterEquipments;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<ClaimAdjuster> getClaimAdjusters() {
        return this.claimAdjusters;
    }

    public void setClaimAdjusters(Set<ClaimAdjuster> claimAdjusters) {
        this.claimAdjusters = claimAdjusters;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<ClaimReport> getClaimReports() {
        return this.claimReports;
    }

    public void setClaimReports(Set<ClaimReport> claimReports) {
        this.claimReports = claimReports;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<Invoice> getInvoices() {
        return this.invoices;
    }

    public void setInvoices(Set<Invoice> invoices) {
        this.invoices = invoices;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<LicenseAdjuster> getLicenseAdjusters() {
        return this.licenseAdjusters;
    }

    public void setLicenseAdjusters(Set<LicenseAdjuster> licenseAdjusters) {
        this.licenseAdjusters = licenseAdjusters;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterClientContactExclude> getAdjusterClientContactExcludes() {
        return this.adjusterClientContactExcludes;
    }

    public void setAdjusterClientContactExcludes(Set<AdjusterClientContactExclude> adjusterClientContactExcludes) {
        this.adjusterClientContactExcludes = adjusterClientContactExcludes;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjusterByNewAdjusterId")
    public Set<BankInvoiceCorrection> getBankInvoiceCorrectionsForNewAdjusterId() {
        return this.bankInvoiceCorrectionsForNewAdjusterId;
    }

    public void setBankInvoiceCorrectionsForNewAdjusterId(
            Set<BankInvoiceCorrection> bankInvoiceCorrectionsForNewAdjusterId) {
        this.bankInvoiceCorrectionsForNewAdjusterId = bankInvoiceCorrectionsForNewAdjusterId;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "adjuster", optional = false)
    public AdjusterAutoAssign getAdjusterAutoAssign() {
        return this.adjusterAutoAssign;
    }

    public void setAdjusterAutoAssign(AdjusterAutoAssign adjusterAutoAssign) {
        this.adjusterAutoAssign = adjusterAutoAssign;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "adjuster", cascade = CascadeType.REMOVE)
    public Set<AdjusterLossType> getAdjusterLossTypes() {
        return this.adjusterLossTypes;
    }

    public void setAdjusterLossTypes(Set<AdjusterLossType> adjusterLossTypes) {
        this.adjusterLossTypes = adjusterLossTypes;
    }

    @Override
    public Integer getId() {
        return getAdjusterId();
    }

    @Override
    public void setId(Integer id) {
        setAdjusterId(id);
    }

}
Run Code Online (Sandbox Code Playgroud)

HelloController.java

@Autowired
@RequestMapping("/testGeneric")
public @ResponseBody String indexTest6(GenericRepository2<Adjuster, Integer> genericDao) throws JsonProcessingException {

Adjuster adjuster = (Adjuster) genericDao.findById(5567);

ObjectMapper mapper = new ObjectMapper();
Hibernate4Module module = new Hibernate4Module();
mapper.registerModule(module);
String result = mapper.writeValueAsString(adjuster);
return result;
Run Code Online (Sandbox Code Playgroud)

}

ESa*_*ala 5

事情不是这样的。

您必须提供一个带有具体类的存储库接口,以便 Spring Data 生成实现。

像这样:

public interface AdjusterRepository extends PagingAndSortingRepository<Adjuster, Long> {

  @Query("SELECT g " // Don't know what this is doing
          + "FROM " + "#{#entityName}" + " g "
          + "WHERE g.#{#entityName}Id = ?1"
         )
  public Adjuster findById(long id);

}
Run Code Online (Sandbox Code Playgroud)

就您而言,我看到您尝试对不同的类重用自定义查询。但是 Spring 会获取你的 GenericRepository 并且不知道该怎么做。

正确的方法是将此 GenericRepositoy 标记为,@NoRepositoryBean这样 Spring 就不会尝试在运行时实例化它,这就是导致错误的原因

所以你可以这样做:

@NoRepositoryBean
public interface GenericRepository<T> extends PagingAndSortingRepository<T, Long> {

  @Query("SELECT g " // Don't know what this is doing
          + "FROM " + "#{#entityName}" + " g "
          + "WHERE g.#{#entityName}Id = ?1"
         )
  public T findById(T id);

}

public interface AdjusterRepository extends GenericRepository<Adjuster> {
    // will inherit from GenericRepository
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,Spring 将忽略 GenericRepository,避免您的错误,并仅为 AdjusterRepository 以及您从 GenericRepository 子类化的任何其他内容创建具体实现。

我没有测试这段代码,可能有一些错别字。我建议阅读 Spring Data 参考中的本节:定义存储库接口

  • 我还建议阅读 Oliver Gierke 的[这个答案](http://stackoverflow.com/a/19443031/1995130),他在其中谈论了使用通用存储库。 (3认同)