I have the below code.
Note that I have an interface MySuperCoolEntityRepositoryContract.
And I have a "concrete interface" MySuperCoolEntityJpaRepository that implements my above MySuperCoolEntityRepositoryContract interface and JpaRepository.
All of that works fine with @ComponentScan.
I am changing my code to "java config", aka a centralized location where I can code up my DI definitions. (Also known as CompositionRoot in some circles).
The issue is when I try to "code up" the concrete for the interface. (Skip down to later in this question.
package com.me.domain.jpaentities;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
@Entity(name = "MySuperCoolEntityTableName")
public class MySuperCoolEntity implements Serializable {
@Id
@Column(name = "CoolSurrogateKeyColumn")
private String coolSurrogateKey;
@Column(name = "CoolMagicValueColumn")
private String coolMagicValue;
public String getCoolSurrogateKey() {
return this.coolSurrogateKey;
}
public void setCoolSurrogateKey(String coolSurrogateKey) {
this.coolSurrogateKey = coolSurrogateKey;
}
public String getCoolMagicValue() {
return this.coolMagicValue;
}
public void setCoolMagicValue(String coolMagicValue) {
this.coolMagicValue = coolMagicValue;
}
}
===============
package com.me.dal.repositories.interfaces;
import com.me.domain.jpaentities.MySuperCoolEntity;
import java.util.Collection;
public interface MySuperCoolEntityRepositoryContract {
Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);
}
=========================
package com.me.dal.repositories;
import com.me.dal.repositories.interfaces.MySuperCoolEntityRepositoryContract;
import com.me.domain.jpaentities.MySuperCoolEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Collection;
@Repository
public interface MySuperCoolEntityJpaRepository extends MySuperCoolEntityRepositoryContract, JpaRepository<MySuperCoolEntity,String> {
Collection<MySuperCoolEntity> findByCoolMagicValue(String coolMagicValue);
}
Now this issue.
package com.me.myapplication.configuration;
import com.me.dal.repositories.MySuperCoolEntityJpaRepository;
import com.me.dal.repositories.interfaces.MySuperCoolEntityRepositoryContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyCompositionRoot {
@Bean
public MySuperCoolEntityRepositoryContract getAMySuperCoolEntityRepositoryContract()
{
return new MySuperCoolEntityJpaRepository(); /* << issue is here, this is an abstract class, aka, an interface with some methods defined */
}
}
Using the super cool JpaRepository "concrete interface" aka "really an abstract class but called an interface" aka "Interface Default Methods" ( see https://dzone.com/articles/interface-default-methods-java ) ........
The exact error is:
MySuperCoolEntityJpaRepository is abstract; cannot be instantiated
I do understand the error. MySuperCoolEntityJpaRepository is abstract. I get that.
But with this super cool "just extend JpaRepository and get all kinds of default functionality".....
How do I register a concrete JpaRepository with Spring DI (specifically with "code it up" java config ?
............
I tried making it a "class".
public class MySuperCoolEntityJpaRepository extends MySuperCoolEntityRepositoryContract, JpaRepository<MySuperCoolEntity,String>
but that wants me to define all those built in methods like "findAll",etc, etc.