With an application.properties like that
application:
api:
clients:
api1:
url: http://url1
api2:
url: http://url2
basicAuth:
username: user2
password: password2
I can do
#Configuration
#ConfigurationProperties(prefix = "application.api")
#Data
public class ApiProperties {
private Map<String, Client> clients;
#Data
public static class Client {
private String url;
private BasicAuth basicAuth;
}
#Data
public static class BasicAuth {
private String username;
private String password;
}
}
And it is working.
But is there a way of retrieving only one client ? So In place of
private Map<String, Client> clients;
I'd like to have something like
#Value("${application.api.clients['api1']}")
private Client client1;
I tried multiple ways of writing it but I always have Could not resolve placeholder...
Is there a solution ?
Looks like this is not possible with nested properties or hierarchal properties.
#Value("${application.api.clients['api1']}")
private Client client1;
But you can try this if you want to retrieve only one client.
#Configuration
#ConfigurationProperties(prefix = "application.api.clients")
#Data
public class ApiProperties {
private Client api1;
#Data
public static class Client {
private String url;
private BasicAuth basicAuth;
}
#Data
public static class BasicAuth {
private String username;
private String password;
}
}
Related
I am new to using nosql databases, specifically mongodb.
My project is based on spring data jpa (postgresql). I would like to know if it is possible to use posgresql and mongodb together? I would like to take data from a postgresql database and write it to mongodb so as not to load postgre.
My Entity for mongodb
#Data
#Document(collection = "exposure")
public class Exposure {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne
#NotNull
private Facility facility;
#ManyToOne
#NotNull
private Investee investee;
#ManyToOne
#NotNull
private Investee investeeName;
#ManyToOne
#NotNull
private Tranche tranche;
}
Repository
#Repository
public interface ExposureRepository extends MongoRepository<Exposure, Long> {
}
DtoService
#Service
#RequiredArgsConstructor
public class DefaultExplosureDtoService implements ExplosureDtoService {
private final FacilityService facilityService;
private final InvesteeService investeeService;
private final ExplosureMapper explosureMapper;
private final ExplosureService explosureService;
#Override
#Transactional
public ExplosureDto create(CreateExplosureDto explosureDto) {
Explosure explosure = new Explosure();
if (explosureDto.getFacilityId() != null) {
explosure.setFacility(facilityService.getById(explosureDto.getFacilityId()));
}
if (explosureDto.getInvesteeId() != null) {
explosure.setInvestee(investeeService.getById(explosureDto.getInvesteeId()));
}
Explosure savedExplosure = explosureService.save(explosure);
return explosureMapper.toExplosureDto(savedExplosure);
}
}
Service
#Service
#RequiredArgsConstructor
public class DefaultExplosureService implements ExplosureService {
private final ExplosureRepository explosureRepository;
#Override
public Explosure save(Explosure explosure) {
return explosureRepository.save(explosure);
}
}
When I run the application, I get a 405 error. And I can’t figure out how to take data from the postgres database and write it to mongodb
I create web application in spring boot using the postgress database.
I want to limit the number of records per page(now it's 30,000 records - it's loading a long time), so what should i do to limit it? I use thymeleaf.
Model:
#Entity(name="articles")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Articles {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long article_id;
private String title;
private String issn;
private String eissn;
private String title2;
private String issn2;
private String eissn2;
private Integer points;
#ManyToMany
#JoinTable(
name = "articles_categories",
joinColumns = #JoinColumn(name = "article_id"),
inverseJoinColumns = #JoinColumn(name = "category_id"))
private List<Category> categories;
....
getters and setters
Repository:
public interface ArticlesRepository extends JpaRepository<Articles,Long> {
}
Controller:
#Controller
#RequestMapping("/articles")
public class ArticlesController {
private ArticleService articleService;
#Autowired
public void setArticleService(ArticleService articleService) {
this.articleService = articleService;
}
#GetMapping
public String getAll(Model model)
{
model.addAttribute("articles", articleService.list());
return "articles";
}
Service:
#Service
public class ArticleService {
#Autowired
private ArticlesRepository articlesRepository;
public ArticleService() {
}
public List<Articles> list(){
return articlesRepository.findAll();
}}
Use Pageable to limit the size of your articles.
public List<Articles> list(int page, int limit){
Page<Articles> pageableArticales = articlesRepository.findAll(PageRequest.of(page, limit);
return pageableArticales.getContent();
}
Note that repository.findAll(pageable) wraps the list of data on Page, which provides getNumber(), getSize(), getNumberOfElements(), getTotalPages(), getTotalElements, etc.
And consider exploring PageRequest and PagedResources as well.
Ihave property class:
#Getter
#Setter
#Component
#ConfigurationProperties(prefix = "my-api")
public class MyApiProperties {
...
private MyClient myClient;
#Getter
#Setter
public static class MyClient {
private String host;
private long connectionTimeout;
private long receiveTimeout;
}
}
I can config it:
my-api:
my-client:
host: http://1...
connection-timeout: 30000
receive-timeout: 60000
And I can Inject it:
#Value("${my-api.my-client.host}")
private String host;
But can I inject full object like this?
#Value("${my-api.my-client}")
private MyClient myClient;
I have configured Spring Data JPA with Redis and using RedisRepositories with provides methods like find(), findAll() etc. All these methods seem to be working just fine, but I am not able to write my custom method like.
RedisEntity findByGenderAndGrade(String gender, String grade);
RedisEntity is a simple POJO Entity class. If you want any more info, please let me know in messages.
Following is my entity:
#Data
#RedisHash("test1")
public class RedisEntity implements Serializable {
#Id
#GeneratedValue
private String id;
private String name;
private String gender;
private Integer grade;
}
Repository:
#Repository
public interface TestRepository extends JpaRepository<RedisEntity, String> {
List<RedisEntity> findAllByGender(String gender);
List<RedisEntity> findAllByGrade(Integer grade);
}
Service/Controller:
#Override
public List<RedisEntity> getById(String id) {
return testRepository.findById(id); //returns data perfectly.
}
#Override
public List<RedisEntity> getAllByGender(String gender) {
return testRepository.findAllByGender(gender); //returns []
}
#Override
public void saveEntity(RedisEntity redisEntity) {
testRepository.save(redisEntity); // saves it in redis perfectly.
}
Also,
findByGender and findAllByGender both give [], although I can see data in my redis database and save it as well.
As requested by FrançoisDupire,
#Configuration
public class RedisConfig {
#Autowired
private DeploymentProperties deploymentProperties;
private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);
#Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("root"));
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
#Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
Also, I had referred this article: Baeldung article on Spring data redis
As mentioned by #JoshJ and verified by myself and others,
The solution to the problem is:
Adding #Indexed annotation
to all those columns/fields which need to be used with all finds.
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
#Indexed
private String gender;
#Indexed
private String grade;
}
We have the Spring Data Redis Library which provides the scope to write the custom method.Attaching Sample code.
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.0.8.RELEASE</version>
</dependency>
Entity Definition
#Data
#RedisHash("EmployeeDetails")
public class RedisEntity {
#Id
private String employeeId;
private String firstName;
private String lastName;
private String gender;
private String grade;
}
Repository Definition
#Repository
public interface RedisEntityRepository extends CrudRepository<RedisEntity, String>{
List<RedisEntity> findAllByGenderAndGrade(String gender, String grade);
}
Implementation
#Component
public class RedisEntityImpl implements RedisEntityService {
#Autowired
private RedisEntityRepository redisEntityRepository;
#Override
public List<RedisEntity> getAllByGenderAndGrade(String gender, String grade) {
return redisEntityRepository.findAllByGenderAndGrade(gender,grade);
}
}
Properties
spring.cache.type = redis
spring.redis.host = localhost
spring.redis.port = 6379
I have a problem with Spring boot.
I created Entity and Repository, but method findByName in Repository isn't work.
My url:
http://localhost:8080/student/search/findByName?name=Artem
In Google chrome: localhost not found, but search is mapped.
Entity:
#Getter #Setter
#Entity #Table(name = "Student")
public class Student extends BaseEntity{
private String name;
private String dateOfBirthDay;
private String sex;
private String phoneNumber;
}
BaseEntity:
#Getter
#Setter
#MappedSuperclass
public class BaseEntity {
#Id #GeneratedValue(strategy = GenerationType.SEQUENCE) #Column protected Long id;
My Repository:
#RepositoryRestResource(collectionResourceRel = "student", path = "student")
public interface StudentRepository extends PagingAndSortingRepository<Student, Long> {
Student findByName(#Param("name") String name);
}
Application:
#SpringBootApplication
#EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Application.yaml:
spring:
application:
name: students
datasource:
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/students
username: postgres
password: postgres
jpa:
hibernate:
ddl-auto: update
server:
port: 8080
I recommend you to create a resource class, works like controller. Here a simple example:
#RestController
#RequestMapping("/yourPath") //students, whatever
public class StudentsResource {
#Autowired
private StudentRepository studentRepository;
//type media that you want to show (json, xml...in this case is JSON)
#RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
// <Student> is the entity, object
#RequestMapping(value = "/yourPath/{studentName}")
public ResponseEntity<Student> findByName(#pathVariable("studentName") String name) {
Student student = studentRepository.findByName(name);
if(student == null){
//handler your own exception here
}
//show the student as json object
return ResponseEntity.status(HttpStatus.OK).body(student);
}
Note: that's the resource class. But your problem is about localhost, so if you are using Spring Boot, see if your "application.properties" is correct. Here my example:
spring.datasource.url=jdbc:mysql://localhost:3306/yourDataBase
spring.datasource.username=yourUser
spring.datasource.password=yourPassword
spring.jpa.hibernate.ddl-auto=update //makes the spring create the database automatic!