Clashes between count() methods - CrudRepository - Spring - java

I prefer to warn you, my english is not perfect but I'll try to do my best.
I'm actually in an internship and my task is to create a webservice. Before this, I'm supposed to work with Maven and create repositories, models and others.
For now, I've got a problem with the repository of a simple Java class.
Here is my class :
package com.XXX;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;
import java.sql.Timestamp;
#Entity
//Generate getters and setters
#Data
//Generate a constructor with to arguments
#NoArgsConstructor
public class Day_ {
#Id
private int day_id_Date;
private Timestamp day_Date;
public Day_(int day_id_Date, Timestamp day_Date) {
this.day_id_Date = day_id_Date;
this.day_Date = day_Date;
}
}
Pretty simple as I said.
Now here comes my repository :
package com.XXX;
import com.XXX.Day_;
import org.springframework.data.repository.CrudRepository;
public interface DayRepository extends CrudRepository<Day_, Long> {
}
I've actually took this from an example on internet. Works fine for him but not for me. I'm getting the following error :
Error:(6, 8) java: types org.springframework.data.repository.Repository<com.atos.test.account.tables.Day_,java.lang.Long> and org.springframework.data.repository.CrudRepository<com.atos.test.account.tables.Day_,java.lang.Long> are incompatible; both define count(), but with unrelated return types
Now I've tried to override the count() method by doing :
package com.XXX;
import com.XXX.Day_;
import org.springframework.data.repository.CrudRepository;
public interface DayRepository extends CrudRepository<Day_, Long> {
#Override
long count();
}
But I get the following error (which is almost the same) :
Error:(6, 8) java: types org.springframework.data.repository.CrudRepository<com.atos.test.account.tables.Day_,java.lang.Long> andorg.springframework.data.repository.Repository<com.atos.test.account.tables.Day_,java.lang.Long> are incompatible; both define count(), but with unrelated return types
Error:(9, 10) java: count() in com.atos.test.account.repository.DayRepository clashes with count() in org.springframework.data.repository.Repository return type long is not compatible with java.lang.Long
I've looked into the CrudRepository class but the methods count() is the same than the one I tried. I've also looked into the Repository class because CrudRepository extends it but there is no method count.
EDIT
So I think I've resolved the problem :
Instead of extending my interface to CrudRepositoryI extended it to Repository. The thing is that I don't know if I can use the same methods ther is in CrudRepository, can I ?

You need to return type "Long".
#Override
Long count();

Related

Cannot set user roles with enum on Spring Boot

I was following a tutorial (https://www.youtube.com/watch?v=TOox3CGarf8) on how to implement JWT authentication on Spring, and it all worked well, that is, until I had to implement the very same InitUsers.java shown in the video.
The problem I'm getting is the following (inside .role(Set.of(Role.ROLE_ADMIN, Role.ROLE_USER) from InitUsers.java, which is shown further below):
Required type: Set<management.relation.Role>
Provided: Set<[path].user.Role>
no instance(s) of type variable(s) exist so that Role conforms to Role inference variable E has incompatible bounds: equality constraints: Role lower bounds: Role
I'm not too well versed in Java, so I'm wondering how I can apply the necessary changes for the code to work, without breaking it and straying away from what is shown in the video.
The relevant implementations are below:
InitUsers.java
import lombok.RequiredArgsConstructor;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import [path].user.JwtUser;
import [path].user.JwtUserService;
import [path].user.Role;
import java.util.Set;
#Component
#RequiredArgsConstructor
public class InitUsers implements CommandLineRunner {
private final JwtUserService jwtUserService;
private final PasswordEncoder passwordEncoder;
#Override
public void run(String... args) throws Exception {
if (jwtUserService.findJwtUserByEmail("emailaaaa#gmail.com").isEmpty()) {
JwtUser u = jwtUserService.save(JwtUser.builder()
.username("Admin")
.email("emailaaaa#gmail.com")
.password(passwordEncoder.encode("testpwd"))
.role(Set.of(Role.ROLE_ADMIN, Role.ROLE_USER))
.build());
u.setEnabled(true);
jwtUserService.save(u);
}
if (jwtUserService.findJwtUserByEmail("someemail#gmail.com").isEmpty()) {
JwtUser u = jwtUserService.save(JwtUser.builder()
.username("Someone")
.email("someemail#gmail.com")
.password(passwordEncoder.encode("123"))
.role(Set.of(Role.ROLE_USER))
.build());
u.setEnabled(true);
jwtUserService.save(u);
}
}
}
Roles.java
public enum Role {
ROLE_USER,
ROLE_ADMIN
}
It turns out I was tricked by IntelliJ's imports. In my JwtUser class, I had the following:
#Column
#Enumerated(EnumType.STRING)
fetch = FetchType.EAGER)
Set<Role> role = new HashSet<>();
The Role there was mistakenly imported from javax.management.Role or something of the like, and not my own implementation in the same package. This was a little frustrating but it serves as a nice lesson - remember to double check your imports!

MongoShell query to MongoRepository

db.getCollection('parentCollection').find({"mapObject.someField" : {$exists: true}})
i want this to convert into method like below
.
#Query("{mapObject.someField :{$exists : true}}")
List<Parent> findByMapKey(String id);
Here i am getting null pointer exception while running application
#Query("{mapObject.someField :{$exists : true}}")
here someField needs to be dynamic not fixed so i want my id to be passed in place of someField
Same question exists here as well
How to get parent object based upon key from child map in MongoRepository JAVA SpringBoot
It's not possible to do with MongoRepository. Instead, use MongoTemplate.
As mentioned above by #Valijon it is not possible with #Query annotation. Still if anyone finds a way please share. Following is how i achieved it using MongoTemplate
package com.somepackage.services;
import org.springframework.stereotype.Service;
import java.util.List;
import com.yourpackagestructure.Parent;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
#Service
public class Service{
private MongoTemplate mongoTemplate;
public Service(MongoTemplate mongoTemplate){
this.mongoTemplate = mongoTemplate;
}
public List<Parent> getParentList(String mapKey){
Query query = new Query();
query.addCriteria(Criteria.where("someMap." + mapKey).exists(true));
List<Parent> parents = mongoTemplate.find(query,Parent.class);
}
}

“ConverterNotFoundException” in Spring boot JPA

I want to get the SearchOutput data object by calling a query(#Query method) with natural joins of 3 tables. but when the query runs it shows an error.
I have tried to fetch the data in my spring boot controller class. But its not working because of the error
package com.example.mysqlproj.model;
import lombok.*;
public class SearchOutput {
private String hotel_name;
private String room_type;
private int price;
}
package com.example.mysqlproj.dao;
import com.example.mysqlproj.model.Room_Type;
import com.example.mysqlproj.model.SearchOutput;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.Collection;
import java.util.Date;
import java.util.List;
public interface RoomTypeDao extends CrudRepository<Room_Type,Integer> {
#Query(value="select new SearchOutput(hotel_name , room_type,(price*(?4)*(?3)*(1.15))) from Room_type natural join Hotel natural join True_contract where (?1 >= start_date and ?2 <= end_date and ?3 <=available_rooms and ?4<= max_adults )", nativeQuery = true)
List<SearchOutput[]> checkHotelList(Date from, Date to, int rooms, int adults, int total_nights);
}
The Error:
No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [com.example.mysqlproj.model.SearchOutput]] with root cause
My target is to fetch a searchOutput object array when the query gets called.
Are there any solutions for this. Thanks in advance
The response type from the query is
List<Map<String, Object>> .
Please change the method return type to this.

How to use a custom function in a jpa query?

I am new to Spring Jpa and Hibernate. I am trying to fetch data using a custom function from an Oracle db. I could define an entity along with its related service, implementation and repository. In addition, I created a new custom Oracle dialect by using registerFunction as you will see below.
So I have two questions:
1) In my Oracle db, the function sits under a different schema. Do I need to specify its schema? If so how? Or will hibernate find it automatically?
I will be asking my second question at the end of this post after providing my full stacktrace...
Here is my full stack trace:
MyOracle10gDialect
package blog;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
public class MyOracle10gDialect extends Oracle10gDialect {
public MyOracle10gDialect() {
super();
registerFunction("my_function", new StandardSQLFunction("my_function"));
}
}
application.properties
...
spring.jpa.database-platform=blog.MyOracle10gDialect
...
Entity:
package blog.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "item", schema = "WOS_SOURCE")
public class WosItem {
#Id
#Column(nullable = false)
private String UT;
#Column(nullable = false)
private String TI;
public String getUT() {
return UT;
}
public void setUT(String UT) {
this.UT = UT;
}
public String getTI() {
return TI;
}
public void setTI(String TI) {
this.TI = TI;
}
public WosItem(String UT, String TI) {
this.UT = UT;
this.TI = TI;
}
public WosItem() { }
#Override
public String toString() {
return "WosItem{" +
"UT='" + UT + '\'' +
", TI='" + TI + '\'' +
'}';
}
}
Service:
package blog.services;
import blog.models.WosItem;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public interface WosItemService {
List<WosItem> findAll();
WosItem findById(String id);
String find_ut(Long ut_seq);
}
Implementation:
package blog.services;
import blog.models.WosItem;
import blog.repositories.WosItemRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class WosItemServiceJpaImpl implements WosItemService {
#Autowired
private WosItemRepository wosItemRepository;
#Override
public List<WosItem> findAll() {
return this.wosItemRepository.findAll();
}
#Override
public WosItem findById(String id) {
return this.wosItemRepository.findOne(id);
}
#Override
public String find_ut(Long ut_seq) {
return this.wosItemRepository.find_ut();
}
}
Repository:
package blog.repositories;
import blog.models.WosItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
#Repository
public interface WosItemRepository extends JpaRepository<WosItem, String> {
#Query("SELECT function('my_function', input) FROM WosItem wos");
String find_ut();
}
So in my Oracle db I can use this function as shown below:
select other_schema.my_function(aa.input) from my_schema.TABLE aa;
For ex. say aa.input is 332708100009 then it returns 000332708100009
As for my second question:
2) How can I carry out this process in jpa? I am aware that my repository is not correct at all. I get an error like "Annotations are not allowed here". I could not find a way to remedy this.
Thanks in advance.
EDIT ON THROWN EXCEPTION:
Caused by: java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: 'function (my_function)'
+-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}
\-[EXPR_LIST] SqlNode: 'exprList'
\-[NAMED_PARAM] ParameterNode: '?' {name=ut_seq, expectedType=null}
Unfortunately if you want to use the JPA 2.1 feature of the custom function call in your Select statement then you will need to perform some additional actions before you can use it.
When you use it in your where statement then it works without any additional actions, but as i wanted to use it for one of my projects inside the select just as you did then you would need to:
1) Extend the hibernate dialect and register your function(s):
package com.mypkg.dialect;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StringType;
public class CustomOracle10gDialect extends Oracle10gDialect {
public CustomOracle10gDialect() {
super();
registerFunction("my_function"
, new StandardSQLFunction("my_function", new StringType()));
}
}
2) Edit your hibernate.dialect property of your session factory to point to that custom implementation:
<property name="hibernate.dialect" value="com.mypkg.dialect.CustomOracle10gDialect"/>
Update
If the function needs to be called from a certain schema then this would be suggested:
registerFunction("my_function"
, new StandardSQLFunction("schema.my_function", new StringType()));
Further reading -> native function calls

How to return a list of custom objects on Objectify

I'm working on an Android project which uses Google App Engine for backend as described here: Using Android & Google App Engine on Android Studio.
I have some model classes on the backend side like User and Item, and I'm trying to return a list of Items user has.
public List<Ref<Item>> getItems() {
return items;
}
When I try to Sync Project with Gradle Files, I get this error:
Error:Execution failed for task ':backend:appengineEndpointsGetClientLibs'.
There was an error running endpoints command get-client-lib: Parameterized type com.googlecode.objectify.Ref≤backend.model.Item> not supported.
I checked some other questions here and was able to build the project without errors by adding #ApiResourceProperty(ignored = AnnotationBoolean.TRUE) annotation to my getter method. But after adding this line, I cannot see this method on Android app side.
Any idea how to make it possible to get a list of Items on Android side?
I did it by saving/retrieving object that contains serialized collection. Class Lesson implements Serializable.
Language.java
import java.io.Serializable;
import java.util.List;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Serialize;
#Entity
public class Language {
#Id
private String key;
private String title;
#Serialize
private List<Lesson> lessons; //here collection
//getters/setters ommited
}
LanguageService.java
import static com.googlecode.objectify.ObjectifyService.ofy;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.Named;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.ObjectifyService;
import com.minspok.entity.Language;
#Api(name = "langapi", version = "v1", description = "langapi")
public class LanguageService {
static{
ObjectifyService.register( Language.class );
}
#ApiMethod(name = "get")
public Language getLanguage(#Named("key") String key){
Language language = ofy().load().key(Key.create(Language.class,
key)).now();
return language;
}
#ApiMethod(name = "create")
public void createLanguage(Language language){
ofy().save().entity(language);
}
}
Helpful reading: https://github.com/objectify/objectify/wiki/Entities

Categories