0

I'm trying to do some basic database operations using a generic repository in Spring Data JPA. However, I keep running into an IllegalArgumentException "Not an managed type: " + whatever class/interface I have my parameter extend.

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

For example, the above complains about class Object, whereas using GenericRepository (a marker interface I was trying to use) it'll complain about interface DatabaseDerived being not a managed type.

I'm simply using @SpringBootApplication for most of my setup, and the answers I've been able to find for this problem either definitely don't work in my case or I can't seem to figure out how to apply them to my setup or I just plain don't understand them. I would be grateful if someone could point me to a useful tutorial (couldn't find one on Google) or walk me through how to get this working with my setup.

Application.java

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

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

}

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>

Adjuster.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);
    }

}

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;

}

wMattDodd
  • 115
  • 1
  • 2
  • 10
  • @dubonzi That doesn't seem to answer my question, so I don't think it's a duplicate. If it is, then my understanding is even more poor than I thought. – wMattDodd Oct 20 '15 at 17:33
  • Do you have all the annotations in your application class? Also check if your Application.java class is in the same package as your repository. If not, follow Oliver Greek's comment on the linked question, and move it to the root of your app. – dubonzi Oct 20 '15 at 17:38
  • `not a managed type` usually occours when the repository you're trying to use isn't mapped by Spring. Also I meant to write 'Oliver Gierke' above, minor typo. – dubonzi Oct 20 '15 at 17:42
  • Can wee see the class you put on the `T` parameter? because you change the `T` for some class, right? – ESala Oct 20 '15 at 17:50
  • @dubonzi I have my entire Application.java posted above. It's in the radius.hibernate package, which is where the repositories are also (for now). I understand that the problem is that it's not mapped by Spring--what I'm hoping for is either a way to make Spring map it or a workaround so that Spring doesn't have to or someone to point out that I'm going down entirely the wrong path here and what I should be doing instead. – wMattDodd Oct 20 '15 at 18:00
  • @wMattDodd what class are you trying to persist? what do you replace the `T` parameter with? – ESala Oct 20 '15 at 18:02
  • @ESala I added one of the classes I'm trying to work with and the controller method that I'm trying to do it at – wMattDodd Oct 20 '15 at 18:06

1 Answers1

5

That's not how it works.

You have to provide a repository interface with a concrete class for Spring Data to generate the implementation.

Like this:

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

}

In your case, I see you try to reuse your custom query for different classes. But Spring will pick up your GenericRepository and won't know what to do.

The correct approach is to mark this GenericRepositoy as @NoRepositoryBean so Spring doesn't try to instantiate it at runtime, which is the cause of your error.

So you can do this:

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

By doing this, Spring will ignore the GenericRepository, avoiding you error, and create a concrete implementation only for AdjusterRepository, and any others that you subclass from GenericRepository.

I didn't test this code, there may be some typos. I recommend reading this section from the Spring Data reference: Defining repository interfaces

ESala
  • 6,878
  • 4
  • 34
  • 55
  • 3
    I also suggest reading [this answer](http://stackoverflow.com/a/19443031/1995130) by Oliver Gierke where he talks about using generic repositories. – dubonzi Oct 20 '15 at 18:23