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.
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 :)
I am working on a Junit5 integration testing with spring-test-mongo. While executing the below code, I am facing invalid method reference error.
import com.jupiter.tools.spring.test.mongo.annotation.MongoDataSet;
import com.jupiter.tools.spring.test.mongo.junit5.meta.annotation.MongoDbIntegrationTest;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
#MongoDbIntegrationTest
public class JUnit5ExampleTest {
#Autowired
private MongoTemplate mongoTemplate;
#Test
#MongoDataSet(value = "/dataset/bar_dataset.json")
void testPopulatingByMongoDataSet() throws Exception {
Bar simpleDoc = mongoTemplate.findById("55f3ed00b1375a48e618300b", Bar.class);
Assertions.assertThat(simpleDoc)
.isNotNull()
.extracting(Bar::getId, Bar::getData);
}
}
Bar.class
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document
#AllArgsConstructor
#NoArgsConstructor
#Data
public class Bar {
#Id
private String id;
private String data;
}
build.gradle:
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.projectlombok:lombok:1.18.20'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
testImplementation 'com.jupiter-tools:spring-test-mongo:0.15'
testImplementation 'org.springframework.boot:spring-boot-starter-data-mongodb:2.5.4'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.5.4'
testImplementation 'org.projectlombok:lombok:1.16.20'
}
test {
useJUnitPlatform()
}
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
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) {
----
};
I have a problem with retrofit and XML, I use SimpleXmlConverterFactory, and I have this error : Caused by: "java.lang.IllegalArgumentException: Could not locate ResponseBody converter for java.util.List.
Tried:
* retrofit2.BuiltInConverters * retrofit2.converter.simplexml.SimpleXmlConverterFactory"
gradle:
compile 'com.google.code.gson:gson:2.8.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile ('com.squareup.retrofit2:converter-simplexml:2.3.0') {
exclude group: 'xpp3', module: 'xpp3'
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
service :
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL)
.client(buildHttpClient())
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
private OkHttpClient buildHttpClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return (new OkHttpClient.Builder())
.addInterceptor(buildDefaultHeadersInterceptor())
.addNetworkInterceptor(buildLogInterceptor())
.build();
}
model :
#Root(name = "item")
public class Item {
#Element(name = "link")
private String link;
#Element(name = "title")
private String title;
#Element(name = "description")
private String description;
public Item() {}
}
xml :
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
<channel xml:lang="fr">
<title>...</title>
<link>http://www.jouars-pontchartrain.fr/</link>
<description>...</description>
<language>fr</language>
<generator>SPIP - www.spip.net</generator>
<image>...</image>
<item xml:lang="fr">
<title>
title here
</title>
<link>
link here
</link>
<description>
description here
</description>
</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
<item xml:lang="fr">...</item>
</channel>
</rss>
Faced with the same problem. The solution is to make the internal class static (or just create a new separate java class). Also add the "Root" annotation for the "channel" node.
#Root(name = "rss", strict = false)
public class ArticleResponse {
#Element(name = "channel")
private Channel channel;
#Root(name = "channel", strict = false)
static class Channel {
#ElementList(inline = true, name="item")
private List<Article> articles;
}
}
The same with the "enclosure" and "source" nodes - create new files or create static internal classes.
public class Enclosure {
#Attribute(name = "url")
private String url;
#Attribute(name = "length")
private long length;
#Attribute(name = "type")
private String type;
}