Mybatis Unable to pass multiple columns from master query to association query - java

Passing multiple columns from the master query to the association query doesn't work.
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'CustomerId' not found. Available parameters are []
#SelectProvider(type = CustomerProvider.class, method = "fetchAllById")
#Results({
#Result(property="accounts",
column="customerId, accountId",
javaType=Account.class,
one = #One(select="com.deeshank.dao.AccountMapper.fetchAccounts",
fetchType = FetchType.EAGER))
})
List<Customer> fetchAllById(CustomerQueryRequest queryRequest);
customerId and accountId comes from the select columsn of the master query.
Any help would be much appreciated.

Using the mybatis version 3.4.1 or later solved the issue.
https://github.com/mybatis/mybatis-3/issues/230

Related

SQL Injection jdbcTemplate

select ID from USER where ID is not null order by ID
Tenacity is throwing SQl injection as high vulnerability.
I tried to resolve as follows :
String sql = "select ID from user where :id is not null order by ID";
NamedParameterJdbcTemplate jdbcNamesTpl = new NamedParameterJdbcTemplate(this.jdbcTemplate);
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("id", "ID");
jdbcNamesTpl.query(sql,parameters,mapper);
But I am getting all records along with null values. Anyone share thoughts or any suggestion to solve ?
Seems to be using the Spring NamedParameterJdbcTemplate - as folks have pointed out, this seems to be using parameterized queries, which should be safe.
It's possible that Tenacity is getting confused because the named parameter is the same as the column - and it believes that you are using a named parameter in the order by clause (which would be a potential SQL injection). Try changing the name of the parameter to something that's not a column name.

GenericJDBCException: could not extract ResultSet

I found similar questions about this error but I can't make it work
I'm working on a java 8, spring 2.6.4 and a MySQL database
I'm trying to do a DELETE native query using JPA and I'm getting this error:
org.springframework.orm.jpa.JpaSystemException: could not extract ResultSet; nested exception is org.hibernate.exception.GenericJDBCException: could not extract ResultSet
this is my query:
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
void deleteWhereSlotid(Integer slotid);
and this is the service:
repo.deleteWhereSlotid(reservationSlot.getId());
I've also tried:
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
Object deleteWhereSlotid(Integer slotid);
//service
Object object= userCourseResRepo.deleteWhereSlotid(reservationSlot.getId());
but it failed
Usually I delete rows with deleteById(id) which comes with spring
The query works though, I tried it on phpMyadmin console and it worked
Someone know what I can try?
The way you have it set up, Spring Data assume you want to perform a query (typically a SELECT). For DELETE and similar statements that don't return a ResultSet you need to provide an additional #Modifying annotation.
#Modifying
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
void deleteWhereSlotid(Integer slotid);
I know is not the best solution, but you can try to use a query SELECT to find your reservation object and then do this repo.deleteById(reservation.getId())
This should allow you to go ahead while you find a better way to do it
If you are using it that way, I believe the query should be:
DELETE a FROM reservation a WHERE a.slotid =:slotid
I am not particularly sure about the code, however, with Mysql, the case seems to be so when giving an alias to the table.
You need to add #Param
#Query(value = "DELETE FROM reservation a WHERE a.slotid =:slotid", nativeQuery = true)
Object deleteWhereSlotid(#Param("slotid")Integer slotid);
As mentioned above, we use the #Param annotation in the method declaration to match parameters defined by name in JPQL/Native query with parameters from the method declaration.

Cannot mix JPA positional parameters and native Hibernate positional/ordinal parameters

I am using Hibernate/JPA to execute native PostGIS queries. The problem with these queries is that they need parameters that are not of the classical X = 'value' form.
My query is :-
#Modifying
#Query(value="UPDATE memo SET readMemo = true and updatedBy_id = ?1 and updatedBy = ?1 and updatedOn = ?2 where assignToUser_id = 1? and readMemo = false and deleted = false ",nativeQuery = true)
void readAllMenoByCurrentUser(Long id, Date updateTime);
Error :-
org.springframework.dao.InvalidDataAccessApiUsageException: Cannot mix JPA positional parameters and native Hibernate positional/ordinal parameters; nested exception is java.lang.IllegalArgumentException: Cannot mix JPA positional parameters and native Hibernate positional/ordinal parameters
Does anyone know how to solve in this case ?
You have "1?" in your query. This will mean it tries to interpret that as a "?" (SQL parameter) rather than positional parameter. Change it to "?1"

selecting maximum field of a column using query dsl predicate

Im new to query dsl.Im using Spring repositories to get the result set.And one case i have to get the maximum of a column and get the fields in to an entity.My predicate code is below.I get error once i run this code.
public static Predicate getMaximum(){
QUserDetails details = QUserDetails.userDetails;
return details.id.eq(details.id.max());
}
And this is how i fetch my resultset using spring jpa
public UserDetails findByCustomerId(Predicate predicate);
And this is the error i get:
org.springframework.data.mapping.PropertyReferenceException: No property find found for type com.example.entity.UserDetails.Can anyone help me acheive what i want here.
You have to define a QueryDslJpaRepository which adds implementation for QueryDslPredicateExecutor
http://docs.spring.io/spring-data/jpa/docs/1.5.0.M1/api/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.html
You can see a tutorial here:
http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-eight-adding-functionality-to-a-repository/
From the QueryDSL email group, apparently what you have to do to select the max ID is this:
from(entity).singleResult(entity.id.max())
So it's
JPAQuery jpaQuery = new JPAQuery(entityManager);
QEntity qEntity = QEntity.entity;
Long maxId = query.from(qEntity).singleResult(qEntity.id.max());

How To Configure Query Cacheing in EclipseLink

I have a collection of states, that I want to cache for the life of the application, preferably after it is called for the first time. I'm using EclipseLink as my persistence provider. In my EJB3 entity I have the following code:
#Cache
#NamedQueries({
#NamedQuery(
name = "State.findAll",
query = "SELECT s FROM State s",
hints = {
#QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase),
#QueryHint(name=QueryHints.READ_ONLY, value=HintValues.TRUE)
}
)
})
This doesn't seem to do anything though, if I monitor the SQL queries going to MySQL it still does a select each time my Session Bean uses this NamedQuery.
What is the correct way to configure this query so that it is only ever read once from the database, preferably across all sessions?
Edit: I am calling the query like this:
Query query = em.createNamedQuery("State.findAll");
List<State> states = query.getResultList();
The solutions posted here not worked for me. But i've made it work with:
#Cache
#NamedQueries({#NamedQuery(
name = "State.findAll",
query = "SELECT s FROM State s",
hints = {
#QueryHint(name = QueryHints.QUERY_RESULTS_CACHE, value = HintValues.TRUE)
}
)})
Just a guess here, but you might try
query.cacheQueryResults();
after you create it but before you getResultList.
-- MarkusQ
I got EclipseLink 1.0.1 cache to work by adding just the query hint:
Query query = em.createNamedQuery("Person.find");
query.setParameter("NAME", name);
query.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase");
return (Person)query.getSingleResult();
I didn't change the entity at all, and haven't yet tried to configure cache using annotations.

Categories