Spring Data JPA-Retrieve generated id when using native sql insert - spring-data-jpa

I have the following native sql insert query when using Spring Data JPA:
#Modifying
#Query(value = "insert into marker(name, event_id, position, tag_ids, gmt_create, gmt_modified)" +
" values(?#{#m.name}, ?#{#m.eventId}, ST_GeomFromText(?#{#m.position})" +
", ?#{#m.tagIds}, ?#{#m.gmtCreate}, ?#{#m.gmtModified})"
, nativeQuery = true)
Marker save(#Param(value = "m") Marker marker);
The question is how to get the auto generated id? Thank you so much!

Related

Native query not working when specifying column name

I am trying to fetch data using native query method. I am able to fetch data using spring data JPA repository declared methods (findAll() etc) and using JPQL Queries.
When I am using Native query method , "select * from" is working. But when I am specifying "select username from " method is not working. Means When specifying column name, it is not working.
I am adding my code like this,
#Query(value = "select u.username from users u" , nativeQuery = true)
List<Users> findByUsername();
But the query using select * from users is working with no problem. Is this native query nature? Or is there any limited type of format the provider defines?
I think the problem is with your return variable.
When you run "*select * from...*" query, you can return list of Users.
However, you want to fetch a column which is probably a varchar, so that you should return List of String:
#Query(value = "select u.username from users u" , nativeQuery = true)
List<String> findByUsername();

Calling StoredProcedure using JPA in Spring Boot

I am trying to call a stored procedure, which is built in mysql, in my Spring boot app using JPA. My stored procedure returns the result which cant be contain in single model as it fetches data from combination of tables.
I can do this with "call " but i guess that is not JPA's way. COuld you please let me know what is the best way to do it?
In case you're using plain JPA you need to do a native query call. Something like below.
Query q = em.createNativeQuery("select my_store_pro(?, ?)");
List<Object[]> results = q.getResultList();
for (Object[] a : results) {
System.out.println("result " + a[0] + " " + a[1]);
}
If you're using Spring Data repositories then you want something like below.
#Query(nativeQuery = true, value = "select my_store_pro(?, ?)")
Date callMyStoreProc(int val1, int val2);

Injecting JSON parameter in nativeQuery of Spring JPA

I have a table with a JSONB column. In my project I am using Spring JPA and to query that column I want to use nativeQuery. My problem is to inject varibale into the query like below:
#Query(nativeQuery = true, value = "SELECT * FROM items WHERE item_json -> 'attributes' #> '{\"Param1\": \"" + :param + "\"}' ")
List<Items> findByParameter(#Param("param") String param);
The above query does not work as param is not considered as JPA parameter. I am wondering if anyone knows how to do this? or I should do it in another way?

How to get primary keys after batch insert in MyBatis

use annotation #Options(useGeneratedKeys = true, keyProperty = "id") to get the generated primary key for single insert is fine for me , but when I use annotation #InsertProvider to make a batch insert , I have no idea how to get the generated primary keys , any comments will be appreciated . thx in advance
Now Mybatis 3.3.1 had supported it. Please see https://github.com/mybatis/mybatis-3/pull/547
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
public interface TestMapper {
...
#Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
#Insert({
"<script>",
"INSERT INTO test_table",
"(column_one, column_two)",
"VALUES" +
"<foreach item='item' collection='list' open='' separator=',' close=''>" +
"(" +
"#{item.columnOne,jdbcType=VARCHAR},",
"#{item.columnTwo,jdbcType=VARCHAR}" +
")" +
"</foreach>",
"</script>"})
void insertBatchTestTable(#Param("list") List<TestObject> testObjs);
}
ps.:
Set keyColumn and keyProperty
Use #Param("list")
MyBatis will set objects keyProperty by reflection
I haven't used annotations with mybatis, only xml. But, I have used both useGeneratedKeys and batch insert, together.
With Mybatis, you have to execute the same query ( One with useGeneratedKeys ) and call the insert repeatedly for each object in your collection. This will map the generated key to your pojo. Flush the session after every N records, and commit.
That's it. I hope you are not using Oracle as your DB. As, with Oracle you'll have to flush after call to insert, which beats to purpose of batch.

How to write JPA Query to the equivalent mysql query

I want to write equivalent JPA query to the following mysql query
select active_package,sum(duration),sum(charge),count(*)
from User
where call_type="MO"
and start_date between '2012-02-01' and '2012-02-09'
group by active_package;
For JPA Query the corresponding Attributes are below.
activePackage,callType,duration,charge,startDate
Entity class is User.
I want to use the createQuery() of JPA.
Can any one tell me or give me the link where can i find the solution for this.
Try this one, it should work, if not, please comment, we will get it work :).
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createQuery(Tuple.class);
Root<User> entity = cq.from(User.class);
cq.multiselect(entity.get("activePackage"),
cb.sum(entity.get("duration").as(Long.class)),
cb.sum(entity.get("charge").as(Double.class),
cb.count(entity).as(Long.class)));
cq.where(cb.equal(entity.get("callType"), "MO"),
cb.between(entity.get("startDate").as(Date.class),
new Date(), new Date()));
cq.groupBy(entity.get("activePackage"));
List<Tuple> resultList = entityManager.createQuery(cq).getResultList();
for (Tuple result : resultList) {
System.out.println(result.get(0) + " " + result.get(1)
+ " " + result.get(2) + " " + result.get(3));
}
Also if you want to filter only by date, but have timestamp in your model, you can check this Compare date's date part only with Timestamp in Hibernate answer.
Also JPA provides constructing result classes as return values, so you can group your columns. Read more.