스프링 애플 리케이션에 별 문제가 없습니다. 것으로, 문제는 스프링 주석 : @Component works, @Repository does not
import com.maciej.Config;
import com.maciej.entities.Etwas;
import com.maciej.services.EtwasService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class Test {
public static void main(String[] args){
AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(Config.class);
Etwas etwas = acac.getBean("etwas", Etwas.class);
etwas.setSth("STATATASTAT");
EtwasService etwasService = acac.getBean("etwasService", EtwasService.class);
for(int i=0; i<=20; i++){
etwasService.save(etwas);
}
System.out.println(etwasService.read(7).toString());
System.out.println(etwas.getSth());
}
}
입니다
: 내 간단한 서비스 클래스 (저장소) 여기import com.maciej.entities.Etwas;
import com.maciej.repository.EtwasRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.List;
HERE IS THE PROBLEM ----- @Component works, while @Repository doesn't
public class EtwasHibernateRepository implements EtwasRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Etwas> findAll() {
return null;
}
@Override
public Etwas create(Etwas etwas) {
entityManager.persist(etwas);
return etwas;
}
@Override
public Etwas read(int id) {
TypedQuery<Etwas> query = entityManager.createQuery("SELECT e FROM Etwas e WHERE e.id=:id", Etwas.class);
query.setParameter("id", id);
Etwas etwas = query.getSingleResult();
return etwas;
}
@Override
public Etwas update(Etwas etwas) {
return null;
}
@Override
public boolean delete(int id) {
return false;
}
}
됩니다
:
import com.maciej.entities.Etwas;
import com.maciej.repository.impl.EtwasHibernateRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class EtwasService {
@Autowired
private EtwasHibernateRepository etwasHibernateRepository;
public boolean save(Etwas etwas){
etwasHibernateRepository.create(etwas);
return true;
}
public Etwas read(int id){
return etwasHibernateRepository.read(id);
}
}
간단한 테스트 클래스는 여기에 내 코드입니다 에 @Component
으로 주석을 달면 모든 것이 잘 동작합니다. 추가 할 때 실제로 apoperly - @Repository
annotation stacktrace : 내가 뭘 잘못했는지 애니 제안이 있니?
PS 코드입니다 정말 간단, 단지 테스트 그래서 :)
스레드에서예외 "주" org.springframework.beans.factory.BeanCreationException에 대해주의를 해달라고에 대한 혼란 및 제작 : 오류 이름이 'etwasService'인 빈을 생성 : autowired 종속성의 주입이 실패했습니다. 상자의 예외는 org.springframework.beans.factory.BeanCreationException입니다 : 수 없습니다 자동으로 묶어 필드 : 개인 com.maciej.repository.impl.EtwasHibernateRepository com.maciej.services.EtwasService.etwasHibernateRepository; 자동으로 묶어 위한 후보로서 자격이 예상 적어도 1 빈 : 종속성 검색 결과 형 [com.maciej.repository.impl.EtwasHibernateRepository] 없음 적격 콩 : 중첩 예외이다 org.springframework.beans.factory.NoSuchBeanDefinitionException 이 종속성. 종속성 주석 : 조직에서 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues (AutowiredAnnotationBeanPostProcessor.java:292) 에서 {org.springframework.beans.factory.annotation.Autowired @는 (= TRUE 필수)} 된 org.springframework.beans에서 .springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean (AbstractAutowireCapableBeanFactory.java:537)에서 (AbstractAutowireCapableBeanFactory.java:1185) .factory.support.AbstractAutowireCapableBeanFactory.createBean (AbstractAutowireCapableBeanFactory.java:475) 의 org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton (DefaultSingletonBeanRegistry.java:228)에서 (AbstractBeanFactory.java:304) 조직 에서. springframework.beans.factory.support.AbstractBeanFactory.doGetBean org.springframework.beans.factory.support.AbstractBeanFactory.getBean (AbstractBeanFactory.java:195)에서 (AbstractBeanFactory.java:300) 된 org.springframework.beans에서 . 팩토리 스니핑 nFactoryInitialization (AbstractApplicationContext.java:760) at org.springframework.context.support.AbstractApplicationContext.refresh org.springframework.context.annotation.AnnotationConfigApplicationContext에서 (AbstractApplicationContext.java:482) . (AnnotationConfigApplicationContext.java:84) com.maciej.test.Test.main (시험에서 . 자바 : 12) sun.reflect.DelegatingMethodAccessorImpl.invoke에서 sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:57) 에서 sun.reflect.NativeMethodAccessorImpl.invoke0 (기본 방법) (DelegatingMethodAccessorImpl.java:43)에서 at java.lang.reflect.Method.invoke (Method.java:606) at com.intellij.rt.execution.application.AppMain.main (AppMain.java:134) 에 의해 발생 : org.springframework.beans. factory.Bean CreationException : 필드를 autowire 할 수 없습니다. private com.maciej.repository.impl.EtwasHibernateRepository com.maciej.services.EtwasService.etwasHibernateRepository; 자동으로 묶어 위한 후보로서 자격이 예상 적어도 1 빈 : 종속성 검색 결과 형 [com.maciej.repository.impl.EtwasHibernateRepository] 없음 적격 콩 : 중첩 예외이다 org.springframework.beans.factory.NoSuchBeanDefinitionException 이 종속성. 종속성 주석 : 에서 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:508) 에서 {org.springframework.beans.factory.annotation.Autowired @는 (= TRUE 필수)} org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues (AutowiredAnnotationBeanPostProcessor.java:289) ... (17) 이상에서 org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java:87) 발생 원인 : org.springframework.beans.factory.NoSuchBeanDefinitionException : 아니요 [com.maciej.r] 형식의 적격 콩 epository.impl.EtwasHibernateRepository]이 (가) 에 종속 됨 : autowire로 간주되는 적어도 하나의 bean이 종속성에 대한 후보가 입니다. 종속성 주석 : 조직에서 org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException (DefaultListableBeanFactory.java:1103) 에서 {@ org.springframework.beans.factory.annotation.Autowired는 (= TRUE 필수)} 된 org.springframework.beans에서 .springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java:858)에서 (DefaultListableBeanFactory.java:963) .factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject (AutowiredAnnotationBeanPostProcessor.java:480) ... 19 더 많은
업데이트 : 구성
import com.maciej.entities.Etwas;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import java.util.Properties;
@Configuration
@ComponentScan
@EnableTransactionManagement
public class Config {
@Bean
public Etwas etwas(){
return new Etwas();
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan(new String[]{"com.maciej.entities"});
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
emf.setJpaVendorAdapter(vendorAdapter);
emf.setJpaProperties(additionalProperties());
return emf;
}
@Bean
public BasicDataSource dataSource(){
BasicDataSource bds = new BasicDataSource();
bds.setUsername("root");
bds.setPassword("maciek");
bds.setUrl("jdbc:mysql://localhost:3306/test");
bds.setDriverClassName("com.mysql.jdbc.Driver");
return bds;
}
private Properties additionalProperties(){
Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "true");
return properties;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf); //entityManagerFactory().getObject()
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
return new PersistenceExceptionTranslationPostProcessor();
}
}
그래서 지금 나는 몇 가지 질문을하고 싶습니다 : 1.What에 대해 @ 서비스? 인터페이스 구현없이 서비스 클래스가 생겼고 @Service가 작동합니다. 2. 봄과 jpa에서 꽤 새로 왔고 실제로 몰랐다. 예외 번역은 무엇을 하는가? 3. 서비스 및 저장소와 "인터페이스가있는 코드"둘 다에 대한 인터페이스를 생성해야합니까? – azalut
'@ Service'에는 현재 추가 동작이 적용되지 않았습니다. 당신의'@ Transactional'은 당신이 인터페이스를 구현하지 않는다는 사실 때문에 cglib 프록시 (클래스 기반)가 생성 될 것입니다. 일반적으로 나는 클래스에 대한 인터페이스를 선호하지만 많은 것들이 10 명의 개발자에게 물어보고 12 개의 답변을 얻습니다. :). –
하지만 인터페이스 프로그래밍에서 한 가지 궁금한 점이 있습니다. 스프링 MVC를 보면서 @Controller @ Services 및 @ Repositories가 있습니다. @ 컨트롤러는 @ Service를 호출하고 @ Service는 @ Repository를 호출해야합니다. 그래서 : 저장소 클래스와 서비스 클래스에 대해 분리 된 인터페이스를 만들면, Repo 인터페이스에 새로운 메소드를 추가 할 때마다 서비스 인터페이스에도 추가해야합니다. 매번 두 번씩 메소드를 추가하지 않으려는 옵션이나 디자인 패턴이 있습니까? – azalut