I have a interface DAO class method that extends CrudRep working without implementation. It is a MVC project with Spring Framework and Hibernate ORM. Here is class:
package eu.execom.collections.dao;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import eu.execom.collections.model.Book;
import eu.execom.collections.model.User;
public interface BookDAO extends CrudRepository<Book, Long> {
public List<Book> findByUser(User user);
}
Related
I am trying to learn Spring Boot and restful application from an online tutorial. But the code I wrote for it somehow gives me an error. I have written a CommandLineRunner class like so:
package com.trial.cas.preload;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.trial.cas.employee.repository.EmployeeRepository;
import com.trial.cas.employee.pojo.Employee;
#Configuration
class LoadDatabase implements CommandLineRunner {
private static final Logger log = java.util.logging.LogManager.getLogManager().getLogger("LoadDatabase");
#Autowired
EmployeeRepository employeeRepository;
#Override
public void run(String... args) throws Exception {
log.info("Preloading " + employeeRepository.save(new Employee("Bilbo Baggins", "burglar")));
log.info("Preloading " + employeeRepository.save(new Employee("Frodo Baggins", "thief")));
}
}
My EmployeeRepository class is like this:
package com.trial.cas.preload;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trial.employee.pojo.Employee;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
My main class is written like:
package com.trial.cas.logging.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class CASLoggingToolApplication {
public static void main(String[] args) {
SpringApplication.run(CASLoggingToolApplication.class, args);
}
}
But when I run the Spring Boot application, the lines in the run method never execute. I have a debug point point in the first line of the run method. But that never gets triggered.
Please help! Thanks in advance.
By default Spring Boot will only scan packages below the package of the main application class (in your example it would be the package com.trial.cas.logging.example and all subpackages.
You can either move the application class to a common super package for your application, or specify all other packages, that should be scanned for beans etc. on the annotation:
#SpringBootApplication(scanBasePackages = {"com.trial.cas.logging.example", "com.trial.cas.preload"})
Try using #Component instead of #Configuration when annotating your LoadDatabase class.
Also, if I recall correctly, for Spring Boot to run properly it is necessary to annotate your EmployeeRepository with #Repository.
Another last tip, try to avoid field injections like:
#Autowired
EmployeeRepository employeeRepository;
It has several drawbacks compared to constructor injection, which are described in detail in this answer: What exactly is Field Injection and how to avoid it?
Instead use constructor injection, like this:
private EmployeeRepository employeeRepository;
#Autowired
public LoadDatabase(EmployeeRepository employeeRepository){
this.employeeRepository = employeeRepository;
}
i'm trying to inject services in Web service Class like this
package com.mobinets.web.nep.backend.soapControllers;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import com.mobinets.web.nep.backend.data.entity.Router;
import com.mobinets.web.nep.backend.data.entity.Version;
import com.mobinets.web.nep.backend.services.RouterService;
import com.mobinets.web.nep.backend.services.VersionService;
#Service
#WebService
public class RouterSoapService extends SpringBeanAutowiringSupport{
#Autowired
private RouterService routerService;
#Autowired
private VersionService versionService;
#WebMethod
public String getRouter(#WebParam int objectId, #WebParam String versionName) {
Version version = versionService.findByName(versionName);
Router router = routerService.findByObjectIdAndVersion(objectId, version.getId());
return router.getName();
}
}
I extended the class from SpringBeanAutowiringSupport and add #Service annotation,
it keeps giving me null on versionService and routerService,
am I missing something ?
Only reason I can think of would be if either of the services
are missing one of the #Component stereotypes (you say they both have #Service
so this should be fine) or
if they rely on any other components which aren't autowired for example if
either has a repository which has been instantiated with the new keyword
they would be excluded from autowiring
This is the userService class that requires a bean of type com.example.repository.userRepository that could not be found
package com.example.services;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.modal.User;
import com.example.repository.userRepository;
#Service
#Transactional
public class UserService {
#Autowired
private userRepository userRepository;
public UserService() {
super();
}
public UserService(userRepository userRepository)
{
this.userRepository = userRepository;
}
public void saveMyuser(User user) {
userRepository.save(user);
}
}
The error message reads :
Consider defining a bean of type 'com.example.repository.userRepository' in your configuration.
This is the repository:
package com.example.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.example.modal.User;
public interface userRepository extends CrudRepository<User,Integer> {
}
this is the application class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
public class TutorialProjectApplication {
public static void main(String[] args) {
SpringApplication.run(TutorialProjectApplication.class, args);
}
}
Seems like userRepository interface is outside of spring-boot default scanning i.e. package of that repository interface is not same or sub-package of the class annotated with #SpringBootApplication. If so, you need to add #EnableJpaRepositories("com.example.repository") on your main class.
Update:
After looking at your updated post, you need to add #EnableJpaRepositories("com.example.repository") to TutorialProjectApplication class
Always keep the #SpringBootApplication main class outer package so that it will automatically scan all the subpackages.
In your case you have main class in package com.example.demo; but the repository in package com.example.repository; which are different packages.so spring boot is not able to find the repositories.
So you have to make spring boot aware of the repositories location.
So now you have 2 solutions.
1.Either put repository class in subpackges of Main class package.
2.Or use #EnableJpaRepositories("com.example.repository") in main class.
In your repository you need to annotate the class
#Repository
public interface userRepository extends CrudRepository<User,Integer> {
}
I'm working with Crud and Spring MVC, and get stuck with duplicating the same code with different repositories;
f.e. if i use Customers, Items and Logins i have
public interface CustomerRepository extends CrudRepository<Customer, Long>{
}
but with Item i have the same stuff:
public interface ItemRepository extends CrudRepository<Item, Long>{
}
Furthermore there are same methods in repositories, like findAll(), findDistinctBy...(), deleteAll(), etc.
As I know the good practice is escaping of code duplication, but where i should do it? In service, using special service interface and implement it by special class, and then specialise the service for each entity? Or I should do it in the my custom repository as they said in official Spring Data JPA reference documentation spring data reference $4.3.1?
My variant for code with service is below.
Common interface for all entities
import org.springframework.data.repository.CrudRepository;
public interface MyCrudService<T>{
<S extends CrudRepository<T, Long>> Iterable<T> findAll(S s);
}
Common class that realises the service
import org.springframework.data.repository.CrudRepository;
public class MyCrudServiceImpl<T> implements MyCrudService<T>{
#Override
public <S extends CrudRepository<T, Long>> Iterable<T> findAll(S s) {
return s.findAll();
}
}
Special service class for Unit entity
#Service
#Transactional
#AllArgsConstructor
public class MyUnitServiceTwo{
UnitRepository unitRepository;
MyCrudServiceImpl crudService;
public List<Unit> findAll1() {
return Lists.newArrayList(crudService.findAll(unitRepository));
}
}
I am trying to create a generic class that will interact with multiple Spring MongoDB repositories. The current code I have compile but blows up with a NULL Exception because both of the repositories are NULL.
Here is my setup, I can't find any documentation that would ensure the autowiring in the wrapper class. Is there something that I am missing that will execute the autowiring. I am using gradle and I added the dependency based off the basic spring mongo project.
Thanks
InstructorDBRepository.java
package courseSystem;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface InstructorDBRepository extends MongoRepository<InstructorDB, String> {
InstructorDB save(InstructorDB saved);
void delete(InstructorDB deleted);
List<InstructorDB> findAll();
}
DBinterface.java
package courseSystem;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
public class DBinterface {
#Autowired
private AcademicRecordDBRepository AcademicRecordRepository;
#Autowired
private InstructorDBRepository InstructorRepository;
public DBinterface() {}
public void deleteAllTables()
{
AcademicRecordRepository.deleteAll();
InstructorRepository.deleteAll();;
}
//Some additional functions
}