Working with MongoDB, I decided username should be unique. Okay, I use #Indexed(unique = true) (application runs fine), but #Indexed(unique = true) isn't working. I can still add 2 users with the same username.
Source (Spring Data: Unique field in MongoDB document) tells me to put spring.data.mongodb.auto-index-creation=true in my application.properties. (also tried putting it in application.yml, gave same error)
Later I also realized the #Size annotation from the jakarta.validation-api doesn't work.
User model:
import org.bson.types.Binary;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.Id;
import javax.validation.constraints.Size;
import java.util.List;
#Document(collection = "users")
public class User {
#Id
private String id;
private Binary profilePicture;
private String bio;
#Size(max = 20)
#Indexed(unique = true)
private String username;
private String password;
private List<Integer> kweets;
private List<User> followers;
private List<User> following;
}
Repository (is just standard):
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface UserRepository extends MongoRepository<User, String> {
}
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
</dependencies>
Id's do get auto-generated though, which means #Id does work.
Where could the problem lay, at first I thought it was just #Indexed, but turns out #Size doesn't work either.
It's fixed. Idk what it was, I stashed all the changes I made and it still works. I didn't change anything and it suddenly worked...
Related
I am a newbie in Spring-boot and was learning to validate constraints, here the #NotBlank, #NonNull doesn't seem to work. What I want is to provide bad request for the null value given. Am I missing something here?
The snippet of model class has been given below:
Person.java
public class Person {
private final UUID id;
#NotBlank
private final String name;
public Person(#JsonProperty("id") UUID id,
#JsonProperty("name") String name){
this.id = id;
this.name = name;
}
And the controller class is given below:
PersonController.java
#PostMapping
public void addPerson(#Valid #NonNull #RequestBody Person person) {
personService.addPerson(person);
}
pom.xml
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
Turns out the problem was in the pom.xml file.
About the validation part: The Validation Starter dependency is no longer included in the web starter dependencies (source: [check][1])
Select it when creating the Spring Boot config or just add at the pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
[1]: import javax.validation.constraints.NotEmpty; not working)
Even though there are already many questions on this topic, non of the answers have helped me so far.
The code of my application.properties:
spring.h2.console.enabled=true
spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:testdb
One example of my entities:
import java.util.Date;
import javax.persistence.*;
import org.springframework.boot.autoconfigure.*;
#Entity
#EnableAutoConfiguration
public class Customer {
#Id
private int customerId;
private String name;
private String street;
private String zip;
private String city;
private Date differenceSince;
private Date lastUpdatedOn;
#OneToOne
private User lastUpdatedBy;
//getters and setters ...
}
The dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
I cannot find the issue, but the H2 Console doesn't contain any tables:
Any ideas on what I am missing?
try to set your application.properties as below
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username= (username)
spring.datasource.password=(password)
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
I created a project using spring boot 2.1.4.RELEASE with the following dependencies:
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I have the following entity and repository:
#Entity
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "last_name")
private String lastName;
#Column(name = "age")
private Integer age;
#Column(name = "createdAt")
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
...
}
PersonRepository.java
#Repository
public interface PersonRepository extends CrudRepository<Person, Integer> {
}
The following is my Application class:
#SpringBootApplication
public class SpringDataApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(SpringDataApplication.class, args);
PersonRepository personRepository = context.getBean(PersonRepository.class);
Person p1 = new Person("Juan", "Camaney", 55);
Person p2 = new Person("Arturo", "Lopez", 33);
Person p3 = new Person("Pancho", "Coscorin", 22);
personRepository.save(p1);
personRepository.save(p2);
personRepository.save(p3);
Iterator<Person> people = personRepository.findAll().iterator();
while (people.hasNext()) {
Person temp = people.next();
System.out.println(temp);
}
}
}
If i execute my application i get the following error:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.devs4j.spring.data.repositories.PersonRepository' available
The solution of it is add the following configuration class:
#Configuration
#EnableJpaRepositories("com.devs4j.spring.data.repositories")
public class JpaConfiguration {
}
But I get the error :
EnableJpaRepositories cannot be resolved to a type
If i downgrade to 2.0.5.RELEASE everything works fine.
I'm confused because when i check the following spring documentation https://docs.spring.io/spring-data/jpa/docs/2.1.6.RELEASE/reference/html/ I see that it is still using #EnableJpaRepositories("com.acme.repositories")
Am i doing something wrong ?
In your configuration.java, have you added the import:
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
I want to integrate Spring and JPA I'm using spring boot. First I tried to create SessionFactory using EntityManager, but I can't. I've already asked this question here Spring boot inject EntityManagerFactory in configuration class. Those pieces of advice didn't help me and It still doesn't work. So now I decided to try to persist by entityManager, but when I persist my object I get an error.
java.lang.IllegalArgumentException: Unknown entity: kz.training.springrest.entity.User
There is my User class
import lombok.*;
import javax.persistence.*;
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
#Entity
#Table(name = "users")
public class User {
#Id
#SequenceGenerator(name = "user_id_seq_gen", sequenceName = "user_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id_seq_gen")
private Long id;
#Column
private String username;
#Column
private String password;
}
Service class
package kz.training.springrest.service;
import kz.training.springrest.entity.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
#Service
public class UserService {
#PersistenceContext
private EntityManager entityManager;
#Transactional
public void insertUser(User user) {
entityManager.persist(user);
}
}
Runner
#SpringBootApplication
#ComponentScan(basePackages="kz.training.springrest")
public class SpringrestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringrestApplication.class, args);
}
}
Database configuration just in case) there is nothing yet
#Configuration
#EnableTransactionManagement
public class DatabaseConfiguration {
}
My dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>
Properties
spring.datasource.url= jdbc:postgresql://localhost:5432/ring
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.show-sql = false
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.hibernate.naming.implicit-strategy = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.properties.hibernate.format_sql=true
#Note: The last two properties on the code snippet above were added to suppress an annoying exception
# that occurs when JPA (Hibernate) tries to verify PostgreSQL CLOB feature.
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
Any ideas?
Add #EntityScan for your SpringrestApplication
#SpringBootApplication
#ComponentScan(basePackages="kz.training.springrest")
#EntityScan("kz.training.springrest.entity")
public class SpringrestApplication {
I'm currently working on an application for an university project. For this project, my team and I are using a Vaadin/Spring/Maven configuration. With this we also include a database connected with repositories.
The repositories are build the following way. First a class for objects:
import javax.persistence.*;
import java.util.Set;
#Entity
#Table (name = "component")
public class Component {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
long id;
String name;
float price;
boolean isVegetarian;
#OneToMany(mappedBy = "component", cascade = {CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.EAGER)
Set<InvoicePosition> Positions;
#ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
ComponentCategory category_id;
String path;
public Component() {
}
public Component(String name, float price, boolean isVegetarian, ComponentCategory category, String path) {
this.name = name;
this.price = price;
this.isVegetarian = isVegetarian;
this.category_id = category;
this.path = path;
}
Then the additional repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface ComponentRepository extends JpaRepository<Component, Long>{}
Then there is a repository for component category, in which we should be able to store a list of components:
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity
#Table(name = "componentCategory")
public class ComponentCategory {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
#OneToMany(mappedBy = "category_id", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
List<Component> components;
public ComponentCategory() { }
public ComponentCategory(String name) {
this.name = name;
components = new ArrayList<>();
}
public void addComponentToCategory(Component component) {
if(!components.contains(component))
{
components.add(component);
component.category_id = this;
}
}
And then the same repository:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface ComponentCategoryRepository extends JpaRepository<ComponentCategory, Long> {}
I am able to create new entries and they are also properly stored in the database. This is all stored in the Application.Java file to start the Vaadin application
ComponentCategory cat1 = new ComponentCategory("examp1");
Component test1 = new Component("example1", 1.25f, true, cat1, "");
Component test2 = new Component("example2", 0.89f, true, cat1, "");
cat1.addComponentToCategory(test1);
cat1.addComponentToCategory(test2);
compcatrep.saveAndFlush(comp); // compcatrep is the ComponentCategoryRepository, which is passed on to the init() function
Now I'm trying to update the entries in the database with the following logic:
Component test11 = new Component("Test", 2.15f, true, compcatrep.getOne((long)4), "");
ComponentCategory comp = compcatrep.getOne((long)4);
comp.addComponentToCategory(test11);
compcatrep.saveAndFlush(comp);
I made sure that there is an entry with the ID (long) 4. It does work and does not show me any error, when I execute the application. Also if I check the length of the stored list in the ComponentCategory after the saveAndFlush():
System.out.println(comp.getComponents().size());
System.out.println(compcatrep.getOne((long)4).getComponents().size());
I do receive different length of the lists. The second Syso does show one less then the first. I tried a lot and did not find the error. Some more information about my issue:
ApplicationProperties in target folder:
spring.datasource.url=jdbc:h2:file:./mensarioDB;DB_CLOSE_ON_EXIT=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
POM.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hs-augsburg.bpap</groupId>
<artifactId>mensario</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mensario</name>
<description>mensario management</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<vaadin.version>8.1.0</vaadin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>