Permítame que le presente mi código a continuación, voy a hacer una pregunta. Primero de todo - Estructura:
Person.java
package com.test.business;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "person")
public class Person {
@Id
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
public Person(){
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
//getters and setters
}
PersonRepository.java
package com.test.repository;
import com.test.business.Person;
import org.springframework.data.repository.CrudRepository;
public interface PersonRepository extends CrudRepository<Person, Long> {
}
PersonService.java
package com.test.service;
import com.test.business.Person;
import com.test.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PersonService{
@Autowired
private PersonRepository personRepository;
public void addNewPerson(){
personRepository.save(new Person(2, "Test2"));
}
}
PersonController.java
package com.test.controller;
import com.test.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@GetMapping(value="/")
@ResponseBody
public String printWelcome() {
personService.addNewPerson();
return "home";
}
MyWebInitializer.java
package com.test.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MyWebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
WebConfig.java
package com.test.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan({ "com.test.controller" })
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
RootConfig.java
package com.test.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableJpaRepositories( basePackages = {"com.test.repository"})
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.test.service", "com.test.repository", "com.test.controller", "com.test.business"})
public class RootConfig {
@Autowired
private DataSource dataSource;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://localhost:5432/postgres");
dataSource.setUsername("postgres");
dataSource.setPassword("postgres");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.POSTGRESQL);
vendorAdapter.setGenerateDdl(true);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(getClass().getPackage().getName());
factory.setDataSource(dataSource());
factory.setJpaProperties(jpaProperties());
return factory;
}
private Properties jpaProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
properties.put("hibernate.show_sql", "true");
return properties;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
return txManager;
}
}
build.gradle
plugins {
id 'java'
}
apply plugin: 'war'
group 'testApp'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile 'org.apache.tomcat:tomcat-catalina:9.0.10'
compile 'org.springframework.boot:spring-boot-starter-data-jpa:2.0.3.RELEASE'
compile 'org.hibernate:hibernate-core:5.3.2.Final'
compile 'org.springframework.data:spring-data-jpa:2.0.9.RELEASE'
compile 'org.postgresql:postgresql:42.2.3'
compile 'org.springframework:spring-webmvc:5.0.7.RELEASE'
compile 'org.hibernate:hibernate-entitymanager:5.3.3.Final'
compile 'javax.xml.bind:jaxb-api:2.3.0'
}
Mientras que la construcción de este proyecto no hay ningún error, pero cuando trato de ejecutar esta aplicación de error muestra la consola:
ERROR org.springframework.web.context.ContextLoader - inicialización de contexto no org.springframework.beans.factory.UnsatisfiedDependencyException: Error al crear el frijol con el nombre 'PersonService': la dependencia Insatisfecho expresado a través del campo 'personRepository'; excepción anidada es org.springframework.beans.factory.BeanCreationException: Error crear bean con el nombre 'personRepository': Invocación de método init fallado; la excepción jerarquizada es java.lang.IllegalArgumentException: No es un tipo administrado: Clase com.test.business.Person
(...)
Causado por: org.springframework.beans.factory.BeanCreationException: Error al crear el frijol con el nombre 'personRepository': La invocación del método init fallado; la excepción jerarquizada es java.lang.IllegalArgumentException: No es un tipo administrado: Clase com.test.business.Person
(...)
Causado por: java.lang.IllegalArgumentException: No es un tipo administrado: Clase com.test.business.Person
¿Porqué es eso? ¿Por frijol PersonService no se pudo crear? Tengo @Entity en Person.java, autowired incluido, RootConfig contiene @ComponentScan
@ComponentScan(basePackages = {"com.test.service", "com.test.repository", "com.test.controller", "com.test.business"})
Puede darle consejos que me ayuda con mi problema?
La primavera puede no identidad de sus clases de entidades como entidades válidos, mientras que la inicialización de contexto. Para que sean válidos por favor intente una de las siguientes:
- Cambiar
factory.setPackagesToScan(getClass().getPackage().getName());
afactory.setPackagesToScan("com.test.business");
. De lo contrario,com.test.config
el paquete será utilizado para la exploración entidad. - Trate de quitar
factory.setPackagesToScan(getClass().getPackage().getName());
y poner@EntityScan("com.test.business")
encima de suRootConfig.java
Ver también Diferencia entre @EntityScan y @ComponentScan