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 {
Related
I am working on java spring shopping mall project. I want to fix this error.
Below is my code.
java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration#4768b95c testClass = com.maven_shopping.repository.ItemRepositoryTest, locations = [], classes = [com.maven_shopping.MavenShoppingApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceLocations = ["classpath:application-test.properties"], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer#4e268090, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer#5939a379, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer#0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer#1f97cf0d, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer#9da1, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer#0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer#44821a96, org.springframework.boot.test.context.SpringBootTestAnnotation#9346081e], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
Item.java:
package com.maven_shopping.entity;
import com.maven_shopping.constant.ItemSellStatus;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
#Entity
#Table(name = "item")
#Getter
#Setter
#ToString
public class Item {
#Id
#Column(name = "item_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false, length = 50)
private String itemName;
#Column(name = "price", nullable = false)
private int price;
#Column(nullable = false)
private int stockNum;
#Lob
#Column(nullable = false)
private String itemDetail;
#Enumerated(EnumType.STRING)
private ItemSellStatus itemSellStatus;
private LocalDateTime regTime;
private LocalDateTime updateTime;
}
ItemRepositoryTest :
package com.maven_shopping.repository;
import com.maven_shopping.constant.ItemSellStatus;
import com.maven_shopping.entity.Item;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.time.LocalDateTime;
import static org.junit.jupiter.api.Assertions.\*;
#SpringBootTest
#TestPropertySource(locations = "classpath:application-test.properties")
class ItemRepositoryTest {
#Autowired
ItemRepository itemRepository;
#Test
#DisplayName("상품 저장 테스트")
public void createItemTest() {
Item item = new Item();
item.setItemName("Test Product");
item.setPrice(10000);
item.setItemDetail("Test Product Detail");
item.setItemSellStatus(ItemSellStatus.SELL);
item.setStockNum(100);
item.setRegTime(LocalDateTime.now());
item.setUpdateTime(LocalDateTime.now());
Item savedItem = itemRepository.save(item);
System.out.println(savedItem.toString());
}
}
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.maven_shopping</groupId>
<artifactId>maven_shopping</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven_shopping</name>
<description>maven_shopping project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<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-thymeleaf</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>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</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>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.6.Final</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties:
#port setting
server.port=80
#MySQL connect setting
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost::3306/shop?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=****
#show query console
spring.jpa.properties.hibernate.show_sql=true
#query hibernate formatting
spring.jpa.properties.hibernate.format_sql=true
#question mark parameter
logging.level.org.hibernate.type.descriptor.sql=trace
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
##Thymeleaf cache ????
#spring.thymeleaf.check-template-location=true
#spring.thymeleaf.prefix=classpath:templates/
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.cache=false
spring.datasource.hikari.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.hikari.jdbc-url=jdbc:mysql://localhost:3306/shop
spring.datasource.hikari.username=root
spring.datasource.hikari.password=****
spring.datasource.hikari.pool-name=TestHikariPool
application-test.properties :
# DataSource Setting
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
#h2 Database dialect Setting
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
application.yml
spring:
datasource:
url: jdbc:h2:tcp://localhost/~/jpashop;
// MVCC=TRUE : 여러개의 요청이 들어왔을때, 빠르게 처리할 수 있도록 도와줌
username: sa
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create
#애플리케이션 실행시점에 내가 가진 SQL문을 다 지우고, 다시 생성함
properties:
hibernate:
show_sql: true
# System.out.println을 통해 sql문이 출력됨 -> 로그로 출력하게 해야함!
format_sql: true
logging.level:
org.hibernate.SQL: debug
org.hibernate.type: trace
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...
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 am creating a Spring Boot application with DB PostgreSQL. My application.properties looks as follow:
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:postgresql://localhost:5432/my-db
spring.datasource.username= myusername
spring.datasource.password= mypassword
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update
The dependencies:
<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>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Simple Model:
#Entity
#Table(name = "questions")
#Data
public class Question {
#Id
#GeneratedValue(generator = "question_generator")
#SequenceGenerator(
name = "question_generator",
sequenceName = "question_sequence",
initialValue = 1000
)
private Long id;
#NotBlank
#Size(min = 3, max = 100)
private String title;
#Column(columnDefinition = "text")
private String description;
}
The Repository:
#Repository
public interface QuestionRepository extends JpaRepository<Question, Long> {
}
And the Controller:
#RestController
public class QuestionController {
#Autowired
private QuestionRepository questionRepository;
#GetMapping("/questions")
public Page<Question> getQuestions(Pageable pageable) {
return questionRepository.findAll(pageable);
}
}
When I tried to run the application, it threw an error:
Caused by: org.hibernate.exception.GenericJDBCException: Unable to
open JDBC Connection for DDL execution
Caused by:
org.postgresql.util.PSQLException: This ResultSet is closed.
Can someone give me a tipp what did I make wrong in the configuration? Thank you so much in advanced!