I am trying to query dynamoDB table ProductInfo based on a field cost.
When I am executing
aws dynamodb execute-statement --statement "SELECT * FROM ProductInfo WHERE cost='1000'" --endpoint-url http://localhost:8000"
from cli, I am getting correct output but when I am trying from springboot I am getting the error
"AmazonDynamoDBException: Can not use both expression and
non-expression parameters in the same request"
For project configuration I have followed this link
My repository looks like below:
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.socialsignin.spring.data.dynamodb.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
#EnableScan
public interface ProductInfoRepository extends CrudRepository<ProductInfo, String> {
#Query(fields = "select * from ProductInfo where cost = :cost")
List<ProductInfo> findAllProductByCost(#Param("cost") String cost);
}
Related
Using Spring boot,I am working on one business use case where i need to modify the JPA query generated at runtime based on configuration.
For Example .. if query that JPA generates is
select * from customers where id=1234
I want to modify it in runtime like based on user's logged in context. (Context has one attribute business unit) like given below ..
select * from customers where id=1234 and ***business_unit='BU001'***
Due to certain business use case restrictions i can't have statically typed query.
Using Spring boot and Postgres SQL.
Try JPA criteria builder , it let you to create dynamics query programmatically.
Take look in this post
What is stopping you to extract the business unit from the context and pass it to the query?
If you have this Entity
#Entity
CustomerEntity {
Long id;
String businessUnit;
//geters + setters
}
you can add this query to your JPA Repository interface:
CustomerEntity findByIdAndBusinessUnit(Long id, String businessUnit)
This will generate the following "where" clause:
… where x.id=?1 and x.businessUnit=?2
for complete documentation check Spring Data Jpa Query creation guide.
you would do something like this, this lets you dynamically define additional predicates you need in your query. if you don't want to have all the conditions in your query with #Query
The below example just adds a single predicate.
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import study.spring.data.jpa.models.TicketPrice;
#Component
public class TricketPriceCriteriaRepository {
#Autowired
TicketPriceJpaRepository ticketPriceJpaRepository;
public List<TicketPrice> findByCriteria(int price) {
return ticketPriceJpaRepository.findAll(new Specification<TicketPrice>() {
#Override
public Predicate toPredicate(Root<TicketPrice> root, CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
if (price > 0) {
predicates.add(
criteriaBuilder.and(criteriaBuilder.greaterThan(root.get("basePrice"), price)));
}
// Add other predicates here based on your inputs
// Your session based predicate
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}
});
}
}
Your base repository would be like
// Other imports
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface TicketPriceJpaRepository
extends JpaRepository<TicketPrice, Long>, JpaSpecificationExecutor<TicketPrice> {}
the model consists basePrice
#Column(name = "base_price")
private BigDecimal basePrice;
I have an error regarding deploying the backend trough docker on localhost 8080 .
When i run the website normally (started the postgres server from inteliji) it works properly.
When i try to deploy it trough docker i get the following error:
org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid = bigint
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Position: 580
The next code is an example of class using UUID
package com.ds.assignment1.ds2021_30244_rusu_vlad_assignment_1.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.UUID;
#Entity
#Data
public class Account {
#Id
#GeneratedValue(generator = "uuid4")
#GenericGenerator(name = "uuid4", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
private String username;
private String password;
private String role;
}
The error shows that the database column is UUID whereas the JPA entity is bigint. I should mention that this may be or may not be about the ID field of this entity.
As #Adrian-klaver said you have to look at position 580 of the SQL query, which you can do by enabling hibernate query logs and looking at the last hibernate SQL query log.
I had a similar problem, spending three days to finally resolve it. My problem was due to having multiple attribute types being different than their database type. As I was migrating from Long id to UUID, it made me confuse figuring out what the cause for my error was.
I have a question regarding how to write HQL query the data and also contain the bridge table column? Here is my ER diagram:
In my TeamRepository code:
package com.crmbackend.allService.teamService.repo;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import com.crmbackend.entity.Team;
public interface TeamRepository extends PagingAndSortingRepository<Team, Integer> {
#Query("select t from Team t")
public List<Team> getAllTeamandDetails();
}
And here is the result:
As you can see I get all teams and all users who belong to that team.
But question here I can't get the extra column - active from team_users entity.
How should I write this HQL code to extra all team and users information and also the data from bridge table?
That's my question, thanks!
The only way to access this column is to map the collection/join table as entity and also map that column. If you are using Hibernate 5.1+ you can write a query like this:
select t, tu
from Team t
left join TeamUser tu on tu.team.id = t.id
I have the following code...
#Table(keyspace = "ks", name="otherThing" )
class Thing extends Serializable{
...
}
However when I run...
repo.findAll()
I get an error that looks like it isn't using the values I provided...
Query; CQL [SELECT * FROM Thing;]; unconfigured table Thing
I would expect
Select * from ks.otherThing;
What am I missing?
Update
I tried converting to the following Pojo
import com.datastax.driver.mapping.annotations.Table;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
#Table( keyspace="ks", name="otherThing" )
public class Thing implements Serializable {
...
}
And my repo is pretty simple...
import org.springframework.stereotype.Repository;
#Repository
public interface ThingRepository extends CassandraRepository<Thing, ThingId> { }
but
thingRepo.findAll();
gives...
Query; CQL [SELECT * FROM thing;]; unconfigured table thing
So the mistake I made was trying to do this with a connection that was set up using my company's spring autoconfig. This allowed me to configure the connection via application.properties. I noticed that the keyspace was previously declared there so I went back and changed my domain object to...
import org.springframework.data.cassandra.core.mapping.Table
#Table("otherThing" )
class Thing extends Serializable{
...
}
Now it is working. Leaving this answer up in case others get confused.
iam using spring data jpa in my project
package com.mf.acrs.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
#Data
#Entity(name= "mv_garage_asset_mapping")
public class GarageAssetMapping implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2535545189473989744L;
#Id
#Column(name="GARAGE_CODE")
private String garageCode;
#Column(name="GARAGE_NAME")
private String garageName;
#Column(name="GARAGE_ADDRESS")
private String garageAddress;
#Column(name="GARAGE_BRANCH")
private String garageBranch;
#Column(name="CONTRACT_NUMBER")
private String contractNumber;
}
this is my entity object
package com.mf.acrs.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.mf.acrs.model.GarageAssetMapping;
public interface GarageAssetMappingRepository extends JpaRepository<GarageAssetMapping, String> {
// #Query(name="select u.CONTRACT_NUMBER from mv_garage_asset_mapping u where u.GARAGE_CODE = ?1", nativeQuery = true) //**QUERY 1**
#Query("select u.contractNumber from mv_garage_asset_mapping u where u.garageCode = ?1") // **QUERY 2**
List<String> findByGarageCode(String garageCode);
}
this is my repository interface
when i use the QUERY 1 in my application the query fired by spring data jpa is
Hibernate: select garageasse0_.garage_code as garage_code1_2_, garageasse0_.contract_number as contract_number2_2_, garageasse0_.garage_address as garage_address3_2_, garageasse0_.garage_branch as garage_branch4_2_, garageasse0_.garage_name as garage_name5_2_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
but when i use QUERY 2 the query fired is
Hibernate: select garageasse0_.contract_number as col_0_0_ from mv_garage_asset_mapping garageasse0_ where garageasse0_.garage_code=?
QUERY 2 gives me desired result.
but my question is why spring data jpa fires a incorrect query in 1st case.
in QUERY 1 hibernate tries to pull all the data fields despite the fact i have explicitly written in query that i want to fetch only one field.
What mistake iam doing in this case?
The method defined in the controller which calls the method is below:
#PostMapping("/searchAssetsAjax")
#ResponseBody
public String searchAssetsAjax(#RequestBody SearchAssetData searchAssetData) throws IOException{
System.out.println("iam in the searchAssetsAjax "+searchAssetData);
System.out.println("iam in the searchAssetsAjax "+searchAssetData.toString());
// System.out.println("throwing exceptions" ); throw new IOException();
System.out.println("hitting the db "+searchAssetData.getGarageCode());
// List<String> contractNums = garageAssetMapRepository.findContractNumberByGarageCode(searchAssetData.getGarageCode());
List<String> contractNums = garageAssetMapRepository.findByGarageCode(searchAssetData.getGarageCode());
System.out.println("############contract num size is "+contractNums.size());
for(String contract: contractNums) {
System.out.println("contract nums are "+contract);
}
return "success";
}