Я старожил, но довольно новичок в весне и друзьях (и, может быть, я старею и ржавею, не будьте ко мне суровы). У меня есть вопрос, который очень, очень похож на тот, который находится в бине Unable to Field, который идентифицирует bean-компонент с именем 'entityManagerFactory' как использующий аннотацию Auto-wiring к Repository , и в настоящее время он меня бьет ... Я не могу чтобы найти ответ на вопрос, почему приложение springboot (это глупая мелочь, которую я делаю в свободное время), похоже, не может автоматически подключать репозитории jpa, как должно. Я (насколько мне известно) выполнил инструкции из связанной проблемы выше (и удалил все известные прямые зависимости спящего режима. Я также включаю свой файл pom в этот вопрос publi c.
<?xml version="1.0" encoding="UTF-8"?>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>se.pointsofinterest</groupId>
<artifactId>poi-restlayer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restlayer</name>
<description>This module contains the rest layer for the application</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!--dependency>
<groupId>se.pointsofinterest</groupId>
<artifactId>dblayer</artifactId>
<version>1.0.0</version>
</dependency-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<!--dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
<version>1.4.200</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Possibly suspect depedencies below! -->
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<version>2.0.4.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.13</version>
</dependency>
</dependencies>
<repositories>
<!-- Main maven repository -->
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Repository where to store our local artifacts (an azure artifacts)! -->
<repository>
<id>joakimhansson</id>
<url>https://pkgs.dev.azure.com/joakimhansson/_packaging/joakimhansson/maven/v1</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Насколько я знаю, у меня нет зависимостей от спящего режима в этом pom.
У меня есть уровень базы данных, который содержит;
- домен (все объекты)
- репозиторий (все соответствующие ссылки на репозиторий)
- Сервис, который содержит уровень сервиса (который определяет несколько более высокий бизнес-логи c для обработки данных).
Это, насколько мне известно, очень похоже на проблему, упомянутую выше.
Я получаю следующую ошибку:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field mapLocationRepository in se.poi.restlayer.dblayer.services.MapLocationService required a bean named 'entityManagerFactory' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Я..э, Функция autowire не работает. Конфигурация моего приложения;
package se.poi.restlayer;
import lombok.extern.slf4j.Slf4j;
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;
import se.poi.dblayer.domain.*;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.repositories.LinksRepository;
import se.poi.dblayer.repositories.MapLocationRepository;
import se.poi.dblayer.repositories.TagDefinitionsRepository;
/**
* * @author Joakim Hansson, 2020
*
*/
@Slf4j
@SpringBootApplication(scanBasePackages = {"se.poi.dblayer.repositories", "se.poi.dblayer.services"})
/*@Import(value={ConfigurationDbLayer.class})
@ComponentScan(basePackages={
"se.poi.dblayer",
"se.poi.dblayer.domain",
"se.poi.dblayer.repositories",
"se.poi.dblayer.services"})
*/
@EntityScan(basePackageClasses = {
Address.class,
Links.class,
MapLocation.class,
MapLocationTagDefinitionsRelation.class,
TagDefinitions.class
})
@EnableJpaRepositories(basePackageClasses = {
AddressRepository.class,
LinksRepository.class,
MapLocationRepository.class,
TagDefinitionsRepository.class})
@ComponentScan(basePackages={
"se.poi.restlayer.dblayer",
"se.poi.restlayer.dblayer.domain",
"se.poi.restlayer.dblayer.repositories",
"se.poi.restlayer.dblayer.services"})
public class Application {
public static void main (String[] args) {
log.info("Starting the main backend for the end customer for us.");
log.info("------------------------------------------------------");
//new BeanConfigurator();
//AutowireCapableBeanFactory f = context.getContext().getAutowireCapableBeanFactory();
//f.autowireBean(new AddressRepository());
SpringApplication.run(Application.class, args);
}
}
Репозиторий;
package se.poi.restlayer.dblayer.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import se.poi.dblayer.domain.Address;
@Repository
//@Component
public interface AddressRepository extends JpaRepository<Address, Long>{
}
Служба;
package se.poi.restlayer.dblayer.services;
import java.util.List;
import java.util.Optional;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import lombok.extern.slf4j.Slf4j;
import se.poi.dblayer.domain.Address;
import se.poi.dblayer.domain.Links;
import se.poi.dblayer.domain.MapLocation;
import se.poi.dblayer.domain.TagDefinitions;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.repositories.LinksRepository;
import se.poi.dblayer.repositories.MapLocationRepository;
import se.poi.dblayer.repositories.TagDefinitionsRepository;
//import org.springframework.web.context.annotation.ApplicationScope;
/**
* Demo backend that accepts up to 100 fishing spots. Data is shared with all
* users.
*/
@Slf4j
//@Service
@Component
public class MapLocationService {
//private List<MapLocation> spots = new ArrayList<MapLocation>();
@Autowired(required = true)
MapLocationRepository mapLocationRepository;
@Autowired(required = true)
TagDefinitionsRepository tagDefinitionsRepository;
@Autowired (required = true)
LinksRepository linksRepository;
@Autowired (required = true)
AddressRepository addressRepository;
public void checkRepositoryStatus () {
log.warn("checkRepositoryStatus");
if (mapLocationRepository == null) {
log.warn("Repository is == NULL!");
} else if (tagDefinitionsRepository == null) {
log.warn("tagDefnitionsRepository == NULL!!");
}
}
public void setMapLocationRepository (MapLocationRepository repository) {
this.mapLocationRepository = repository;
}
public Repository getMapLocationRepository() {
return (Repository) mapLocationRepository;
}
@PostConstruct
private void init() {
log.info("init called!");
}
/**
* Retrieves a list of map locations to the caller. As the
* map location is lazilly loaded the caller needs to instantiate each object
* using @link getManagedMapLocation
*
* @return list of map locations.
*/
@Transactional
public List<MapLocation> getAll() {
log.info("getAll");
//return Collections.unmodifiableList(spots);
return mapLocationRepository.findAll();
}
@Transactional
public MapLocation getManagedMapLocation (MapLocation mapLocation) {
Optional<MapLocation>mapLocationResponse = mapLocationRepository.findById(mapLocation.getId());
mapLocation = mapLocationResponse.get();
mapLocation = getAllLinks(mapLocation);
mapLocation = getAllAddresses(mapLocation);
mapLocation = getAllTags(mapLocation);
return mapLocation;
}
@Transactional
public MapLocation getAllAddresses (MapLocation mapLocation) {
log.info("getAllAddresses called!");
mapLocation.getAddresses();
log.info("Retrieved (" + mapLocation.getAddresses().size() + ") objects in list!");
return mapLocation;
}
@Transactional
public MapLocation getAllLinks (MapLocation mapLocation) {
log.info("getAllLinks called!");
mapLocation.getLinks();
log.info("Retrieved (" + mapLocation.getLinks().size() + ") objects in list!");
return mapLocation;
}
@Transactional
public MapLocation getAllTags (MapLocation mapLocation) {
mapLocation.getTagDefinitions();
return mapLocation;
}
/**
* The spot object is a non managed object as returned by this service from
* the getAllFunction.
*
* @param spot
*/
@Transactional
public MapLocation addSpot(MapLocation spot) {
log.info("addSpot called!");
MapLocation mapLocation = mapLocationRepository.save(spot);
for (Links i : spot.getLinks()) {
log.info("links: " + i.getLink() + " id = " + i.getId());
i.setMaplocation(mapLocation);
linksRepository.save(i);
}
for (Address i : spot.getAddresses()) {
log.info("Address: " + i.getAddressline1() + " id = " + i.getId());
i.setMaplocation(mapLocation);
addressRepository.save(i);
}
for (TagDefinitions i : spot.getTagDefinitions()) {log.info("Tagdefinition: " + i.getTag());}
return mapLocation;
}
@Transactional
public void delete (MapLocation mapLocation) {
/* Implementaion */
log.info("delete on maplocation is called!");
for (Links i: mapLocation.getLinks()) {
log.info("Removing link (" + i.getId() + ")");
linksRepository.delete(i);
}
for(Address i : mapLocation.getAddresses()) {
log.info("Deleting address (" + i.getId() + ")");
addressRepository.delete(i);
}
log.info ("remove mapLocation.getId (" + mapLocation.getId() + ")");
mapLocationRepository.delete(mapLocation);
/* * * */
}
/**
*
* @param name Marker name, which should be used on the map.
* @param links the links associated with the marker
* @param address the address to the nearest street address
* @param latitude
* @param longitude
* @param tags the list of tag (in string form) for the marker.
* @return
*/
public MapLocation prepareSpot (Long id,
String name,
List<Links> links,
List<Address> addresses,
double latitude,
double longitude,
List<TagDefinitions> tagDefinitions) {
/* Implementation */
MapLocation mapLocation = new MapLocation();
mapLocation.setId (id);
mapLocation.setName (name);
mapLocation.setLinks (links);
mapLocation.setAddresses (addresses);
mapLocation.setLatitude (latitude);
mapLocation.setLongitude (longitude);
mapLocation.setTagDefinitions (tagDefinitions);
mapLocation.setAddresses (addresses);
mapLocation.setLinks (links);
/* * * */
return mapLocation;
}
}
И подходящий объект домена;
package se.poi.restlayer.dblayer.domain;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Simple data object representing a marker on a map.
*/
@Entity
@Data
@Table(name="MAP_LOCATION")
@AllArgsConstructor
@NoArgsConstructor
public class MapLocation implements Serializable {
/**
*
*/
private static final long serialVersionUID = -590067472197846904L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="latitude", nullable = false)
private Double latitude;
@Column(name="longitude", nullable = false)
private Double longitude;
@Column(name="name", length = 128)
private String name;
@ManyToMany (fetch=FetchType.EAGER) //(mappedBy = "mapLocations")
@JoinTable(name="maplocations_tagdefinitions",
joinColumns= @JoinColumn(name="mapLocations"),
inverseJoinColumns = @JoinColumn(name="tagDefinitions"))
private List<TagDefinitions>tagDefinitions = new ArrayList<>();
@OneToMany(mappedBy="maplocation")
private List<Links> links;
@OneToMany(mappedBy="maplocation")
private List<Address> addresses;
public MapLocation(double latitude, double longitude, String name, List<TagDefinitions>tagDefinitions) {
this.latitude = latitude;
this.longitude = longitude;
this.name = name;
this.tagDefinitions = tagDefinitions;
/* * * */
}
}
Тест, который запускает;
package se.poi.restlayer;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Test;
//import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import lombok.extern.slf4j.Slf4j;
import se.poi.restlayer.controller.GetTagsController;
/**
*
* @author fmanh
*/
@RunWith(SpringRunner.class)
@WebMvcTest(GetTagsController.class)
@AutoConfigureRestDocs(outputDir="target/snippets")
@Slf4j
public class WebLayerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetTags() throws Exception {
log.info ("mockMvc == " + ((this.mockMvc==null)?"NULL":"INSTANTIATED"));
log.info("KALLE");
this.mockMvc.perform (get("/retrievealltags")); //.
//andExpect(status().isOk()).
//andExpect(content().json("")).
//andDo(print()).
//andDo(document("/retrievealltags"));
}
}
The application.properties
server.port=8080
# Ensure application is run in Vaadin 14/npm mode
vaadin.compatibilityMode = false
logging.level.org.atmosphere = warn
#
# Settings for the internal H2
#
#spring.datasource.url = jdbc:h2:file:~/test
#spring.datasource.driverClassName = org.h2.Driver
#spring.datasource.username = sa
##spring.datasource.password =
#spring.jpa.databse-platform = org.hibernate.dialect.H2Dialect
#spring.h2.console.enabled = true
#spring.h2.console.path = /h2-console
#hibernate.dialect = H2
#
# Set up the postgres database
#
spring.datasource.url = jdbc:postgresql://localhost:5432/postgres
spring.datasource.username = postgres
spring.datasource.password = d1d4a5baa55f4f70a90e12bc95473833
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming.implicit-strategy = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.properties.hibernate.format_sql = true
spring.jpa.properties.hibernate.generate_statistics = true
logging.level.org.hibernate.type=trace
logging.level.org.hibernate.stat=debug
#spring.jpa.hibernate.ddl-auto=none
# Following values available;
# validate, update, create, create-drop, none
#server.port = 8443
#server.ssl.key-store-type = PKCS12
#server.ssl.key-store = classpath:keystore.p12
#server.ssl.key-store-password = Pur3Life
#server.ssl.key-alias = tomcat
#security.require-ssl = true
Любая помощь приветствуется! Я тщетно пытался погуглить (возможно, мой гугл-фу не на высоте, или я пропустил что-то очевидное), если да, то не стесняйтесь указать на это. Tar-архив софта можно получить, если у вас wi sh (секретов здесь нет). Пожалуйста, помогите мне немного научиться мудрости!
РЕДАКТИРОВАТЬ!
Я понял, что мое описание неполное: мое решение содержит рестлер, который содержит следующий контроллер;
package se.poi.restlayer.controller;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import se.poi.dblayer.ConfigurationDbLayer;
import se.poi.dblayer.domain.Address;
import se.poi.dblayer.domain.Links;
import se.poi.dblayer.domain.MapLocation;
import se.poi.dblayer.domain.TagDefinitions;
import se.poi.dblayer.repositories.AddressRepository;
import se.poi.dblayer.services.MapLocationService;
import se.poi.dblayer.services.TagDefinitionsService;
import se.poi.restlayer.model.AddressObject;
import se.poi.restlayer.model.LinkObject;
import se.poi.restlayer.model.MapLocationList;
import se.poi.restlayer.model.MapLocationObject;
import se.poi.restlayer.model.TagDefinitionObject;
import se.poi.restlayer.model.TagDefinitionsList;
/**
* The
* @author Joakim Hansson
*/
@RestController
//@EnableJpaRepositories(basePackages={"se.poi.dblayer.repositories"})
//@EntityScan(basePackages={"se.poi.dblayer.domain"})
//@ComponentScan(basePackages={"se.poi.dblayer.services", "se.poi.dblayer.repositories"})
@Slf4j
//@Import(value={ConfigurationDbLayer.class})
public class GetTagsController {
//@Autowired
//AddressRepository a;
@Autowired
TagDefinitionsService tagDefinitionService;
//@Autowired
MapLocationService mapLocationService;
//private TagDefinitionsService tagDefinitionService = new TagDefinitionsService ();
//private MapLocationService mapLocationService = new MapLocationService ();
@GetMapping("/retrievealltags")
public TagDefinitionsList retrieveAllTags () {
/* Implementation */
if (tagDefinitionService==null) {log.error ("tagDefinitionsService: NULL!");}
List<TagDefinitions> list = tagDefinitionService.getAllTagDefinitionsInFull();
TagDefinitionsList tagDefinitionsList = new TagDefinitionsList();
ArrayList<TagDefinitionObject> tagDefinitions = new ArrayList<TagDefinitionObject>();
for (TagDefinitions item : list) {
TagDefinitionObject tagDefinition = new TagDefinitionObject ();
tagDefinition.setId (item.getId());
tagDefinition.setDescription (item.getDescription());
tagDefinition.setTag (item.getTag());
tagDefinition.setParentId (null);
tagDefinitions.add (tagDefinition);
}
tagDefinitionsList.setTagDefinitions(tagDefinitions);
/* * * */
return tagDefinitionsList;
}
@GetMapping("/retrieveMarkers")
public MapLocationList retrieveMarkers () {
/* Implementation */
// Retrieve all the data from the service...
List<MapLocation> l = mapLocationService.getAll();
// Convert to...
MapLocationList mapLocationList = new MapLocationList ();
ArrayList<MapLocationObject> ll = new ArrayList<MapLocationObject> ();
for (MapLocation item: l) {
MapLocationObject mapLocationObject = new MapLocationObject ();
mapLocationObject.setId (item.getId ());
mapLocationObject.setLatitude (item.getLatitude ());
mapLocationObject.setLongitude (item.getLongitude ());
mapLocationObject.setName (item.getName ());
mapLocationObject.setLinks (copyLinksList (item.getLinks ()));
mapLocationObject.setAddresses (copyAddressList (item.getAddresses ()));
ll.add (mapLocationObject);
}
/* * * */
return mapLocationList;
}
/* Private functions
* **********************************************************************/
/**
* Copies data from the database model to the rest API model.
*
* @param links
* @return
*/
private List<LinkObject> copyLinksList (List<Links>links) {
/* Implementation */
ArrayList<LinkObject> ll = new ArrayList<LinkObject> ();
for (Links item: links) {
LinkObject linkObject = new LinkObject();
linkObject.setId (item.getId());
linkObject.setLink (item.getLink());
ll.add(linkObject);
}
/* * * */
return ll;
}
/**
*
* @param address
* @return
*/
private List<AddressObject> copyAddressList (List<Address>address) {
/* Implementation */
ArrayList<AddressObject> ll = new ArrayList<AddressObject> ();
for (Address item: address) {
AddressObject addressObject = new AddressObject();
addressObject.setId (item.getId ());
addressObject.setAddressline1 (item.getAddressline1 ());
addressObject.setAddressline2 (item.getAddressline2 ());
addressObject.setAddressline3 (item.getAddressline3 ());
addressObject.setCity (item.getCity ());
addressObject.setPostcode (item.getPostcode ());
ll.add(addressObject);
}
/* * * */
return ll;
}
}
Это означает, что приложение пытается создать экземпляр контроллера, который содержит аннотацию autowire в сервисе dblayer, а этот сервис dblayer, в свою очередь, содержит аннотацию autowire в репозитории. Именно эта цепь идет на юг. Извините за упущение.
EDIT; Я сейчас широко экспериментирую; autowire просто не работает. ВЗДОХ!. Забавно то, что я вижу в своих файлах журнала, что найдено 4 объекта jpa, но я просто не могу заставить Autowired работать с этими репозиториями ... Google швы указывает на то, что это обычная проблема, но, похоже, нет быть четким решением.