MongoShell query to MongoRepository - java

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);
}
}

Related

How Execute Stored Procedure using JPA annotation #NamedStoredProcedureQuery

How convert this procedure execution using #NamedStoredProcedureQuery?
I have this SQL, It's OK!
SQL (it's Works OK):
USE [INTEGRADOR]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[SP_VW_PEDIDOSDECOMPRA_SGM]
#CODIGO = 71648
SELECT 'Return Value' = #return_value
GO
In Java i Try this, but not working. idUsuarioAutenticado is #CODIGO = 71648
JAVA (Error when compile) :
#NamedStoredProcedureQuery(
name = "listarComprasMicrosigaProc",
procedureName = "INTEGRADOR.DBO.SP_VW_PEDIDOSDECOMPRA_SGM",
resultClasses = AcompanhamentoCompraPortalEntity.class,
parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, type = Long.class)
}
)
public List<AcompanhamentoCompraPortalEntity> listarComprasMicrosigaProc(#Param("idUsuarioAutenticado") Long idUsuarioAutenticado);
Not compile.
I received this errors:
The annotation #NamedStoredProcedureQuery is disallowed for this location
My imports (Java) :
import java.util.List;
import java.util.Set;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.StoredProcedureParameter;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
Instead of at field/attribute level, you have to add the #NamedStoredProcedureQuery annotation and its details at class level:
#Entity
#NamedStoredProcedureQuery(
// further specifications ...
)
public class MyEntity {
// fields, getter/setter methods, etc.
}
With that corrected, the error (message)
The annotation #NamedStoredProcedureQuery is disallowed for this location
should disappear.
Hope it helps.

“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.

Spring JPA / Hibernate is calling full update before a special update using #Modifying and #Query

I have a spring repository for the class Business:
public interface BusinessRepository extends JpaRepository<Business, String> {
That include a simple method to update just one field (updateDatetime):
#Modifying
#Query("update Business business set business.updateDatetime = :updateDatetime where business.businessKey = :businessKey")
int setUpdateDatetimeForBusiness(#Param("updateDatetime") String updateDatetime, #Param("businessKey") String businessKey);
The problem is when I call this method:
businessRepository.setUpdateDatetimeForBusiness(business.getUpdateDatetime(), business.getBusinessKey());
The logs shows the following:
Hibernate: update business set name=?, timezone=?, updatedatetime=? where business_id=?
Hibernate: update business set updatedatetime=? where business_id=?
The method is calling a full update for the entity, then calling my update. What should I change to call just the second update?
#Query(value="update something", nativeQuery=true)
nativeQuery=true try to add this
update
Sorry for didn't read the question carefully.
As the inflammation you provided, I can't find the problem out. But I do have
suggestions for you.
The entity managed by EntityManager can automatically persist into database, and you log Hibernate: update business set name=?, timezone=?, updatedatetime=? where business_id=? seems like it updated all the fields? If so, the update much more likely called by EntityManager.
And you can change the flushMode to COMMIT to see if this make changes. (just for testing if the problem is caused by EntityManager's automatically update)
eg: spring.jpa.properties.org.hibernate.flushMode=COMMIT in spring boot.
My test code:
service:
import cn.eeemt.dao.TagRepository;
import cn.eeemt.entity.Tag;
import cn.eeemt.service.TagService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Optional;
#Service
public class TagServiceImpl implements TagService {
#Resource
private TagRepository tagRepository;
#Override
public void update(String newDescription) {
Tag tag = step1(newDescription);
step2(tag.getDescription(), tag.getId());
}
#Transactional
public Tag step1(String newDescription) {
Optional<Tag> byId = tagRepository.findById(1);
Tag tag = byId.orElseThrow(RuntimeException::new);
System.out.println(tag);
tag.setDescription(newDescription);
// tagRepository.save(byId.get()); // I did not update it!!!
return tag;
}
private void step2(String description, Integer id) {
tagRepository.updateSome(description, id);
}
}
repository:
import cn.eeemt.entity.Tag;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
public interface TagRepository extends JpaRepository<Tag, Integer> {
#Modifying
#Transactional
#Query("update Tag tag set tag.description = :description where tag.id = :id")
void updateSome(#Param("description") String description, #Param("id") int id);
}
when spring.jpa.properties.org.hibernate.flushMode=ALWAYS
log looks like:
Tag{id=1, name='ffadsfasd', description='dasfadsg', articles=[]}
Hibernate: update tag set description=?, name=? where id=?
Hibernate: update tag set description=? where id=?
when spring.jpa.properties.org.hibernate.flushMode=COMMIT
log looks like:
Tag{id=1, name='ffadsfasd', description='dasfadsgaaer', articles=[]}
Hibernate: update tag set description=? where id=?
If the problem it what I said above, it's not good idea to change flushMode unless it's suitable for you situation. You'd better to refactor you code for better design.
information may help you:
Transactional saves without calling update method
Entity Lifecycle

Error while using Jparepository

I was using JPA repository to get user data and store it in a list . Then is was going to iterate that list of users to get all the users. But there is an error in the forEach statement(Syntax error).
code:
package com.mohit.Services;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.mohit.Repo.userrepo;
import com.mohit.beans.users;
public class loginuser {
#Autowired
userrepo Repo;
public void loguser(users user){
String pass =user.getPass();
String uname =user.getName();
List<users> userlist=Repo.findAll();
forEach( users u : userlist){
}
}
}
There is no foreach keyword in java, need to use for, so you have error in source code, please try below code for cycle, instead of your's:
for(users u : userlist){
}

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

Categories