This question already has answers here:
How to load a large number of strings to match with oracle database?
(3 answers)
Closed 6 years ago.
0I have this method:
public List<Product> getProductsByListIds(List<Long> ids) {
String query = "from Product pr where pr.id in(:ids)";
List<Product> products= (List<Product>) getSession().createQuery(query)
.setParameterList("ids", ids).list();
return products;
}
This method is OK, my only problem is when the ids.size() >1000
I'm trying to find a convincing solution to this problem.
My advice would be to take a step back and look at the design and what you're trying to achieve, passing hundreds of parameters into an SQL statement is not going to be very efficient and I'd be surprised if it's the most elegant solution to your requirement.
Without knowing more about how this method is called and where this list of ids comes from it's difficult to give concrete advice, however I would recommend that you look into using joins if possible.
Related
This question already has answers here:
PreparedStatement IN clause alternatives?
(33 answers)
Closed 3 years ago.
i have this query in spring:
private String SQL_Clear_Deleted_Options = "DELETE FROM vote_votes WHERE poll_id=? AND option_id NOT IN ?"
my problem is with second ?. the correct form would be (id1,id2,id3,...). how can i pass a string like cl="0,1,2,3,6" to this query?
i'm using jdbcTemplate. so it would be
jdbcTemplate.update(SQL_Clear_Deleted_Options, id,cl)
what should be cl?
You can use setArray of PreparedStatement to set multiple values.
https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setArray(int,%20java.sql.Array)
And the array should be of the correct type, so you could create it with the Connection.createArrayOf function:
https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#createArrayOf(java.lang.String,%20java.lang.Object[])
You can see a lot of discussions about that topic on SO already, e.g.:
How to use an arraylist as a prepared statement parameter
Edit: Forgot to mention: The JdbcTemplate should set the Parameter correctly when the Array is given as parameter.
This question already has answers here:
Hibernate Criterion IN Clause 1000 break up
(3 answers)
Java Oracle exception - "maximum number of expressions in a list is 1000"
(7 answers)
Closed 5 years ago.
I am constructing a hibernate query and I pass a list of String values into the IN clause. That list sometimes happens to be more than 1000 values so I receive an error. I have looked up some solutions like breaking that clause into smaller ones or making temporary table, but none of them showed how actually it is better to work with variable list.
So if I had something like:
SELECT * FROM MY_TABLE WHERE NAME IN (list).
What would be the best way to handle this?
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am currently working with a PostgreSQL database, Spring and Hibernate. I have one table where attribute correlation_id is unique. Each time before I add a new element first I have to check does any item with a new correlation_id already exist in db or not.
For this case I have implemented recursive function that will generate a new correlation_id and check does it exist or not in db. It means this function will make a call on db each time so sometimes it can be just one call but sometimes i could be five, ten or even more. This example is shown in example one.
Example1:
private String generateId() {
String myId = StaticFunction.generateMyId();
MyMessages doesExist = MyServiceDaoImpl.checkDoesItExistInDB(myId);
if(doesExist != null) {
generateId();
}
return myId;
}
In the second example I suppose that I could create just one call to db and retrieve all items and put them into collection. Then I am able to via stream to search for specific item using also recursive function.
Example2:
private String generateId(List<MyMessages> messages) {
String myId = StaticFunction.generateMyId();
MyMessages myMessage = messages.stream().filter(m ->
m.getCorrelationId.equals(myId)).findFirst().orElse(null);
if (MyMessages != null) {
generateId(messages);
}
return myId;
}
My question is whats is the best approach to make this thing right? Do you have some other solutions? What are the advantages and disadvantages of above examples?
If you cannot use db generated ids, as suggested in the comments, you could use a UUID generator to create the PKs. The probabilities of collision are so low it's not worth checking in the db.
For generating UUIDs in Java take a look at http://docs.oracle.com/javase/7/docs/api/java/util/UUID.html
There's nothing wrong with case 1, DB can do lookups very effeciently when the column is indexed. But - you need to do the DB access.
The second case looks much faster (iterate in memory would be much faster than any DB access), however it has drawbacks: You have to keep all your messages (or at least their correlation ids) in memory and when having A LOT of data, you're scr.. you will have bad time to fix it
As well consider scalability where multiple instances of your application could access a DB.
Therefore I'd suggest to let the database generate the key (you can use e.g. SERIAL data type) and Hibernate returns the generated keys when saving the object. If you need custom ids (generated by your app), you can use uuid where there's low probability of the value conflict
As well you can use UPSERT syntax (INSERT .... ON CONFLICT (correlation_id) ...)
Have fun
This question already has answers here:
What is difference between setMaxResults and setFetchSize in org.hibernate.Query?
(3 answers)
Closed 7 years ago.
I have the below code and trying to limit the number of records retrieved. (LIMIT), but i always get all the rows. I see forums recommending me to use Query, but is not possible to achieve it using criteria ?
Criteria criteria = session.createCriteria(Application.class)
.add(Restrictions.gt("lastModifiedOn", applicationLastRunTime))
.add(Restrictions.eq("lead", false))
.addOrder(Order.asc("lastModifiedOn"));
criteria.setFetchSize(40);
criteria.list()
try to use:
public Criteria setMaxResults(int maxResults)
Set a limit upon the number of objects to be retrieved.
Parameters:
maxResults - the maximum number of results
Returns:
this (for method chaining)
Criteria criteria = session.createCriteria(Application.class)
.add(Restrictions.gt("lastModifiedOn", applicationLastRunTime))
.add(Restrictions.eq("lead", false))
.addOrder(Order.asc("lastModifiedOn"));
criteria.setMaxResults(40);
criteria.list()
more info: What is difference between setMaxResults and setFetchSize in org.hibernate.Query?
This question already has an answer here:
Case-insensitive ordering using Hibernate Criteria
(1 answer)
Closed 8 years ago.
Here, i am posting what i need from you!
DetachedCriteria criteria = DetachedCriteria.forEntityName(DomainEntity.tbl_user.toString);
criteria.addOrder(Order.asc("username"));
List<User> user = dao.getEntities(criteria);
This code is working fine, But sorting the names first UpperCase letters then LowerCase letters. I don't want that way.
But, I want both sorting at a time. Based on the alphabetical order. Here, i am using MySQL database.
Are you looking for case-insensitive ordering ? Then try this :
Order.asc("username").ignoreCase()