Maze
Maze

Reputation: 398

How to code the query function in the implementation of a crud repository

So typically, I have just had a single interface that implements a CrudRepository and put my @Query in there. However, for this I have a DAO class that is the repo and a DAOImpl that implements that repo. So, I have the implement the method I just want to use a query for and return that query as a List of strings. My question is how do I code the part in the implementation to just pass that List of Strings through?

public interface DealerDAO {
    /**
     * @return List of Marketing Orgs
     */
    public Map<String, MarketOrg> getMarketStructure();

    @Query(
            value="SELECT DISTINCT ...",
            nativeQuery = true)
    List<String> findDealerCode(String marketOrg, String region, String district);
}
@Service
public class DealerDAOImpl implements DealerDAO {
    @PersistenceContext
    private EntityManager em;


    public Map<String, MarketOrg> getMarketStructure() {
        HashMap<String, MarketOrg> mktOrgs = new HashMap<String, MarketOrg>();
        Query q = em.createNativeQuery("SELECT DISTINCT ....");
        List<Object[]> marketEntities = q.getResultList();
        /* Extra code */

        return mktOrgs;
    }


    @Override
    public List<String> findDealerCode(String marketOrg, String region, String district) {
        //This should return something, not null.
        return null;
    }

Upvotes: 0

Views: 273

Answers (1)

Ananthapadmanabhan
Ananthapadmanabhan

Reputation: 6216

So,I do not understand your need entirely but My guess is that you do not want to provide the implementation for the findDealerCode() method but still wants to add an implementation for getMarketStructure() to return a Map. If so, instead of providing an implementation for the DealerDAO interface, if you have java8 compatibility why don't you use a default method implementation in the interface itself. That way you could still extend the CRUD repository, use the default spring implementation and still get what you want to achieve.Like :

public interface DealerDAO extends CrudRepository<Obj,Obj> {
    /**
     * @return List of Marketing Orgs
     */
    default public Map<String, MarketOrg> getMarketStructure() {
        HashMap<String, MarketOrg> mktOrgs = new HashMap<String, MarketOrg>();

        /* Extra code */

        return mktOrgs;
    }

    @Query(
            value="SELECT DISTINCT ...",
            nativeQuery = true)
    List<String> findDealerCode(String marketOrg, String region, String district);
}

but this means that the method cannot access the state of the instance.Default methods should only be used to delegate calls to other repository methods. Default methods - by definition - cannot access any state of an instance (as an interface has none). They only can delegate to other interface methods or call static ones of other classes.

or in spring-boot way you could have separate interfaces for these methods , if you need to have the persistance context in the getMarketStructure() method . Like :

@Repository
public interface DealerDAO extends CrudRepository<Obj,Obj>, DealerRepositoryCustom {
    @Query(
            value="SELECT DISTINCT ...",
            nativeQuery = true)
    List<String> findDealerCode(String marketOrg, String region, String district);
}

public interface DealerRepositoryCustom {
   public Map<String, MarketOrg> getMarketStructure();
}

then you could have the implementation for the DealerRepositoryCustom interface in a class like :

@Repository
@Transactional(readOnly = true) // if you don't plan on modifying
public class DealerCustomRepositoryImpl implements DealerRepositoryCustom {
    @PersistenceContext
    private EntityManager em;

    @Override
    public List<String> findDealerCode(String marketOrg, String region, String district) {
        //This should return something, not null.
        return null;
    }
}

For reference read.

Upvotes: 1

Related Questions