I have a very simple Spring Boot MVC project in which I try to use the DomainClassConverter to load the Entity directly. But it seems that the DomainClassConverter is not found. I have the following error when accessing to accessing to the 'localhost:8080/one/2' url:
Cannot convert value of type 'java.lang.String' to required type 'com.example.test.data.Customer': no matching editors or conversion strategy found
But The DomainClassConverter should be enabled by Spring Boot and manage the conversion.
I tryed also to enable it explicitely via the #EnableSpringDataWebSupport annotation but it didn't work neither.
Here is my controller code:
#Controller
public class TestController {
#Autowired
private CustomerRepository customerRepository;
#GetMapping("/all")
public void all(Model model) {
Iterable<Customer> customers=customerRepository.findAll();
model.addAttribute("customers",customers);
};
#GetMapping("/one/{customer_id}")
public void one(#PathVariable("customer_id") Customer customer, Model model) {
model.addAttribute("customer",customer);
};
}
The Customer coode:
#Entity
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Getter
private Long id;
#Getter
#Setter
private String firstName;
#Getter
#Setter
private String lastName;
protected Customer() {
}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
The CustomerREpositoy:
public interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
Customer findById(long id);
}
The application :
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class);
}
}
And finally the build.graddle:
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
// testImplementation 'org.springframework.security:spring-security-test'
}
test {
useJUnitPlatform()
}
Any idea?
you try to get the customer_id (path variable) as a Customer object. hence, get the above error when you try to access localhost:8080/one/2.
change the customer_id (path variable) data type to relevant data type (String, int etc.) as follows,
#GetMapping("/one/{customer_id}")
public void one(#PathVariable("customer_id") String customerId, Model model) {
----
};
Related
Currently Im new to spring and I tried the example (https://spring.io/guides/gs/rest-service/) they have on their website. I think I followed all steps correctly, but with a httpget in postman I only get this response:
"timestamp": "2023-01-04T09:23:03.965+00:00",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/greeting"
Here is the Code:
Greeting.java:
package com.example.restservice;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
GreetingController.java:
package com.example.restservice;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}
and here is the build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.1'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-rest'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-web-services'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.session:spring-session-core'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
}
tasks.named('test') {
useJUnitPlatform()
}
I looked through the linked github and saw, that they have a RestServiceApplication.java, which is never created in the tutorial. After I added that, everything works fine now :)
This error appears, I read on the sites to fix it I need to add various dependencies. I have already added everything I could, it has not disappeared. Tell me what is wrong please.
my implementation
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
// postgresql
implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.19'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'
implementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'
implementation group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.4.30.Final'
//lombok
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
testCompileOnly 'org.projectlombok:lombok:1.18.20'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
// spring-security-taglibs
implementation group: 'org.springframework.security', name: 'spring-security-taglibs', version: '5.4.2'
// javax.servlet
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
Class User
import lombok.Data;
import org.springframework.data.annotation.Id;
import javax.persistence.*;
import java.util.Set;
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String username;
#Column
private String password;
#Transient
#Column
private String passwordConfirm;
#Column
#ManyToMany(fetch = FetchType.EAGER)
private Set<Role> roles;
}
Class Role
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.security.core.GrantedAuthority;
import javax.persistence.*;
import java.util.Set;
#Data
#Entity
#Table(name = "t_role")
public class Role implements GrantedAuthority {
#Id
#Column
private Long id;
#Column
private String name;
#Transient
#ManyToMany(mappedBy = "roles")
private Set<User> users;
public Role(Long id) {
this.id = id;
}
public Role(Long id, String name) {
this.id = id;
this.name = name;
}
#Override
public String getAuthority() {
return getName();
}
Class WebSecurityConfig
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserService userService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf()
.disable()
.authorizeRequests()
//Доступ только для не зарегистрированных пользователей
.antMatchers("/registration").not().fullyAuthenticated()
//Доступ только для пользователей с ролью Администратор
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/news").hasRole("USER")
//Доступ разрешен всем пользователей
.antMatchers("/", "/resources/**").permitAll()
//Все остальные страницы требуют аутентификации
.anyRequest().authenticated()
.and()
//Настройка для входа в систему
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/");
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}
}
Logs
Error starting ApplicationContext. To display the conditions report re-run
your application with 'debug' enabled.
2021-05-05 12:32:55.159 ERROR 11924 --- [ main]
o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean
with name 'entityManagerFactory' defined in class path resource
Invocation of init method failed; nested exception is
org.hibernate.AnnotationException: No identifier specified for entity:
com.project.project.model.Role
at
at
... 17 common frames omitted
Process finished with exit code 1
Application.properties
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/main_bd
spring.datasource.username=mysql
spring.datasource.password=mysql
spring.jpa.show-sql=true
spring.jpa.generate-ddl=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
Class UserService
#Service
public class UserService implements UserDetailsService {
#PersistenceContext
private EntityManager em;
#Autowired
UserRepository userRepository;
#Autowired
RoleRepository roleRepository;
#Autowired
BCryptPasswordEncoder bCryptPasswordEncoder;
#Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("Пользователь не найден");
}
return (UserDetails) user; // ПРОВЕРИТЬ!
}
public User findUserById(Long userId) {
Optional<User> userFromDb = userRepository.findById(userId);
return userFromDb.orElse(new User());
}
public List<User> allUsers() {
return userRepository.findAll();
}
public boolean saveUser(User user) {
User userFromDB = userRepository.findByUsername(user.getUsername());
if (userFromDB != null) {
return false;
}
user.setRoles(Collections.singleton(new Role(1L, "ROLE_USER")));
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
userRepository.save(user);
return true;
}
public boolean deleteUser(Long userId) {
if (userRepository.findById(userId).isPresent()) {
userRepository.deleteById(userId);
return true;
}
return false;
}
}
I tried all the tips I found and nothing helped. Can you please tell me what is my mistake here?
the error is org.hibernate.AnnotationException: No identifier specified for entity: com.project.project.model.Role.
Hibernate is telling you that your entity Role has not an id associated. This is because you #Id annotation in your entity is from org.springframework.data.annotation package, and not from javax.persistence.
Try changing the import for #Id to javax.persistence.Id
Getting Build error when using #Query in Dao class (room persistence library)
I am using both java and kotlin in my project so there may be problem of dependencies, I tried different implementation and kapt but no luck.
My dependencies (see at last for room persistence library)
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//noinspection GradleCompatible
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
implementation 'com.google.android.material:material:1.1.0-alpha05'
implementation "org.jetbrains.anko:anko:$anko_version"
implementation "org.jetbrains.anko:anko-commons:$anko_version"
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.dagger:dagger:2.19'
implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
implementation 'com.google.firebase:firebase-database:16.1.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.19'
kapt 'com.google.dagger:dagger-android-processor:2.19'
kapt 'com.google.dagger:dagger-compiler:2.19'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.google.code.findbugs:jsr305:3.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//BUTTER KNIFE
implementation 'com.jakewharton:butterknife:10.1.0'
kapt 'com.jakewharton:butterknife-compiler:10.1.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
//crashlytics
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
// Update your firebase-core version, if it's lower than v11.4.2
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.0.5'
//firebase messaging
implementation 'com.google.firebase:firebase-messaging:17.5.0'
//sms retrival
implementation 'com.google.android.gms:play-services-base:16.1.0'
implementation 'com.google.android.gms:play-services-identity:16.0.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.gms:play-services-auth-api-phone:16.0.0'
implementation project(':library')
//for intro
implementation 'com.github.AppIntro:AppIntro:5.1.0'
//picaso
implementation 'com.squareup.picasso:picasso:2.71828'
//room
def room_version = "1.1.1"
implementation "android.arch.persistence.room:runtime:$room_version"
kapt "android.arch.persistence.room:compiler:$room_version"
My Entity Class
#Entity(tableName = "product")
public class Product
{
#PrimaryKey
#ColumnInfo(name = "id")
public Integer id;
#ColumnInfo(name = "category")
public String category;
#ColumnInfo(name = "name")
public String name;
#ColumnInfo(name = "price")
public Double price;
#ColumnInfo(name = "desc")
public String desc;
#ColumnInfo(name = "img_url")
public String img_url;
public Product(Integer id, String category, String name, Double price, String desc, String img_url) {
this.id = id;
this.category = category;
this.name = name;
this.price = price;
this.desc = desc;
this.img_url = img_url;
}
}
My Dao Class which is building good when not using #Query,
but when #Query is in used, building error causes.
#Dao
public interface CartDao
{
#Query("SELECT * FROM product")
ArrayList<Product> getAllProduct();
#Delete
void delete(Product cart);
}
Build Error
org.gradle.execution.MultipleBuildFailures: Build completed with 1 failures..
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:kaptPureshDebugKotlin'...6 more
Caused by: org.gradle.api.GradleException: Compilation error. See log for more details
at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwGradleExceptionIfError(tasksUtils.kt:14)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:135)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:152)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runCompilerAsync(GradleKotlinCompilerRunner.kt:147)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner.runJvmCompilerAsync(GradleKotlinCompilerRunner.kt:87)
at org.jetbrains.kotlin.gradle.internal.KaptWithKotlincTask.compile(KaptWithKotlincTask.kt:72)..34 more
#Dao
public interface CartDao
{
#Query("SELECT * FROM product")
ArrayList<Product> getAllProduct();
#Delete
void delete(Product cart);
}
Instead of ArrayList use List
I also had this same error run clean build, invalidate caches or try run with
gradlew assembleDebug
This will show you where is the problem in you app.
I've got the entity manager in the parent test class
#RunWith(SpringRunner.class)
#SpringBootTest(
properties = {
"spring.profiles.active=test",
"spring.config.name=app-test"})
public abstract class ViewerTestBase extends DbBuilderImpl {
#Autowired EntityManager em;
The entity manager here is OK. DbBuilder sets up test data.
In the #repository it is null
#Repository public class PaymentTransactionDao {
#Autowired EntityManager em;
Causing the test case to fail.
The entity manager is mapped to the h2 database for tests.
The persistence config class is boiler plate
#Configration
#EnableTransactionManagement
public class PersistenceConfig {
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean em = builder.dataSource(viewerDataSource())
.packages("viewer.model")
.persistenceUnit("viewer")
.build();
return em;
}
#Bean
public PlatformTransactionManager transactionManager(
EntityManagerFactory viewerEntityManagerFactory) {
return new JpaTransactionManager(pspEntityManagerFactory);
}
#Bean
#Primary
#ConfigurationProperties(prefix = "viewer.dbo.datasource")
public DataSource viewerDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConfigurationProperties(prefix = "viewer.auth.datasource")
public DataSource authDataSource() {
return DataSourceBuilder.create().build();
}
Setup with spring boot starter jpa
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-devtools")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'com.h2database', name: 'h2'
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile group: 'org.springframework.boot', name: 'spring-boot-test'
testCompile group: 'org.springframework.boot', name: 'spring-boot-test-autoconfigure'
In order to put EntityManager within persistence context, change:
#Autowired
private EntityManager entityManager;
To
#PersistenceContext
private EntityManager entityManager;
A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction, or an extended unit of work.
Official documentation hibernate definitions
Solved this through the use of constructor injection.
Change #Repository constructor
public class ViewItemDao {
#PersistenceContext
protected EntityManager em;
public ViewItemDao(EntityManager em) {
this.em = em;
}
Change test. Note that the entity manager was being injected into the test classes with just #RunWith(SpringRunner.class) and #SpringBootTest
#Test
public void testQueryId() throws InvalidSearchParameterException, SearchFailureException {
generateTransaction("639051cc-4b19-4383-9c9a-89a80cd2a2f9");
ViewItemDao viewItemDao = new ViewItemDao(em);
I did change #Autowired to #PersistenceContext without noticing a difference.
I'm trying to create a very simple example rest service that produces JSON. My understanding is that Jersey should auto discover the Jackson libraries (if they're on the classpath) and the JSON marshalling should happen automatically.
The following error is reported when I call GET. Am I using the appropriate dependencies for this to work or am I missing something more fundamental?
SEVERE: MessageBodyWriter not found for media type=application/json, type=class jsonex.Person, genericType=class jsonex.Person.
Dependencies
I'm using Gradle with the gretty plugin applied and these dependencies:
dependencies {
compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2+'
runtime group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.23'
runtime group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.7'
}
Application class
package jsonex;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.Collections;
import java.util.Set;
#ApplicationPath ("services")
public class PersonApp extends Application {
#Override
public Set<Object> getSingletons() {
return Collections.singleton(new PersonService());
}
}
Service class
package jsonex;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("people")
public class PersonService {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Person getPerson() {
Person me = new Person();
me.setFirstName("Dave");
me.setLastName("R");
return me;
}
}
POJO
package jsonex;
public class Person {
String firstName, lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Thanks!
In order to consume/produce JSON in Jersey with Jackson you must register the Jackson feature (JacksonFeature) in your application. It's not auto discoverable as some other Jersey features.
After adding the jersey-media-json-jackson module to your dependencies, register the JacksonFeature in your Application / ResourceConfig subclass:
#ApplicationPath("/api")
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(JacksonFeature.class);
return classes;
}
}
#ApplicationPath("/api")
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(JacksonFeature.class);
}
}
The steps to use Jackson as a JSON provider for Jersey are fully described in this answer. For more details, also check the Jersey documentation.