I am trying to do fetch the data from database using ScrollableResults. Part of my code is below :
List list = null;
ScrollableResults items = null;
String sql = " from " + topBO.getClass().getName(); // topBO is my parent class so i pass the any of my child class name .
StringBuffer sqlQuery = new StringBuffer(sql);
Query query = sessionFactory.getCurrentSession().createQuery(sqlQuery.toString());
items = query.scroll();
int i = 0;
TopBO topBO;
while(items.next())
{
topBO= (TopBO) items.get()[i];
list.add(TopBO2); // got the exception at this line.
i++;
topBO= null;
}
items.close();
If i run the above code i am getting runtime error like java.lang.NullPointerException
You are trying to add the value in list which is not initialize.
It may helps you :
List list = new ArrayList();
replace with
List list = null;
I think topBO= (TopBO) items.get()[i]; is causing the problem.
I would suggest that you use result set transformer of query something like this
Query query = sessionFactory.getCurrentSession().createQuery(sqlQuery.toString());
list=query.setResultTransformer(Transformers.aliasToBean(YourClassName.class)).list();
Related
I am trying to write a method that returns me IDs (as a List ) of all records from a collection that have a certain status.
I am looking for a solution, but unfortunately I cannot find anything correct.
I currently have something like this:
List<String> getAllLecturersIdList() {
MongoCollection<Document> collection.mongoTemplate.getCollection("lecturers");
MongoCursor<Document> cursor = collection.find().iterator();
ArrayList<String> listOfIDS = new ArrayList<>();
while (cursor.hasNext()) {
listOfIDS.add(cursor.next().getObjectId("_id").toString());
}
return listOfIDS;
}
This method returns me a list of IDs of all lecturers.
The lecturer entity also has a "status" field with values like ACTIVE, LEAVE, FIRED and so on.
I would like to have only IDs of lecturers who have ACTIVE status to be returned to me.
How to do it to have only entities with ACTIVE status when returning from the collection, and not to clean the repository / services level?
Thanks for help in advance!
Important - I don't want an entity structure to be created in the application.
Therefore, the solution cannot contain a POJO / Entity Class and here is the problem (I cannot use e.g. Criteria, because every example is with defined entity )
You can fallback to the low level MongoOperations#executeQuery method if there is no result type mapping your query results:
List<String> getAllLecturersIdList() {
Query query = new Query();
query.fields().include("_id");
query.addCriteria(Criteria.where("status").is("ACTIVE"));
ArrayList<String> listOfIDS = new ArrayList<>();
mongoTemplate.executeQuery(query, "lecturers", document -> listOfIDS.add(document.getObjectId("_id").toString()));
return listOfIDS;
}
The following should work:
List<String> getAllLecturersIdList() {
MongoCollection<Document> collection.mongoTemplate.getCollection("lecturers");
MongoCursor<Document> cursor = collection.find().iterator();
ArrayList<String> listOfIDS = new ArrayList<>();
while (cursor.hasNext()) {
Document document = cursor.next();
if (document.getString("status") == "ACTIVE") {
listOfIDS.add(document.getObjectId("_id").toString());
}
}
return listOfIDS;
}
So, I read my MongoDB this way:
mongo = new MongoClient("localhost", 27017);
// Accessing the database
MongoDatabase database = mongo.getDatabase("myDb");
MongoCollection<Document> collection = database.getCollection("searchresults");
// Getting the iterable object
FindIterable<Document> iterDoc = collection.find();
int i = 1;
// Getting the iterator
Iterator it = iterDoc.iterator();
while (it.hasNext()) {
System.out.println(it.next());
i++;
}
}
As you can see, each line has several columns: Title, etc. So, when I iterate over myDB, i want to parse each line by its value instead of get all in one line.
Any suggestions?
You can try reading into a Document structure, then run another loop across each of the entries. This will give each value on its own line.
FindIterable<Document> iterDoc = database.getCollection("").find();
for(Document doc : iterDoc) {
for(Map.Entry<String, Object> entry : doc.entrySet()) {
System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
}
}
If you only want certain keys, use a projection in your find query
This is not a fitting answer to your question, but i would look in to a concept thats called Object-Document-Mapping (ODM). It simplifies some boilerplate code that you have to care about. A common library for MongoDB-ODM is called Morphia :)
I have the following json document. I want to retrieve only all the names. Given a movie name I need to return all the user names.
I am using Java, if you can also assist me in Java it will be awesome. How can I do this?
You can use something like if you're using Mongo 3.x driver.
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection<Document> movieToUsers = db.getCollection("movieToUsers");
Bson filter = Filters.eq("movieName", "Green Mile");
List<String> names = movieToUsers.distinct("user.name", filter, String.class).into(new ArrayList<>());
You org.json library
sample
//Json object
JSONObject obj = new JSONObject(" .... ");
String id = obj.getString("_id");
String movieName = obj.getString("movieName");
//Json array
JSONArray users = obj.getJSONArray("user");
for (int i = 0; i < arr.length(); i++)
{
String name = user.getJSONObject(i).getString("name");
String name = user.getJSONObject(i).getString("date");
}
You can use distinct() function with a query as follows:
mongo shell:
var results = db.movieToUsers.distinct("user.name", { "movieName": "Green Mile" });
printjson(results);
In Java, this is implemented by the distinct() method, for example
// Get a new connection to the db assuming that it is running
MongoClient m1 = new MongoClient();
// use test as a database or use your own database
DB db = m1.getDB("test");
// fetch the collection object
DBCollection coll = db.getCollection("movieToUsers");
// call distinct method with the query and store results in variable results
List results = coll.distinct("speed", new BasicDBObject("movieName", "Green Mile"));
// iterate through the results list and print the names
for(int i=0;i<results.size();i++){
System.out.println(results.get(i));
}
I am creating new collection from existing one.
In this code, keywords will be stored into a list from file.
BufferedReader keyword = new BufferedReader(new FileReader("Leave.txt"));
String str;
List<String> list = new ArrayList<String>();
while((str = keyword.readLine()) != null)
{
list.add(str);
}
String[] psentiments = list.toArray(new String[0]);
Here, I am checking with my collection weather any of status has the specific word. if it finds then it will insert into the new collection. It works quite well but if it compares with same status for different keyword, it throws me an error.
Insert code:
MongoCursor<Document> cursor = collection1.find().iterator();
try {
while (cursor.hasNext()) {
Document dr = cursor.next();
String stat = dr.getString("status");
for(String i:psentiments){
if(stat.contains(i)){
//System.out.println( stat+"-->"+i+ counter);
createcollection(dr,collection1, new ObjectId(dr.get("_id").toString()),newcoll);
counter++;
}
}
}
} finally {
cursor.close();
}
}
private static void createcollection(Document dr, MongoCollection<Document> collection1, ObjectId objectId, MongoCollection<Document> newcoll) {
//I need help here.. insert document without duplicate
newcoll.insertOne(dr);
}
Result:
Exception in thread "main" com.mongodb.MongoWriteException: E11000 duplicate key error collection: Brexit.Leave index: id dup key: { : ObjectId('573334f5fbfb8711f0c7ac44') }
at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:523)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:306)
at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:297)
at twitter.sample.createcollection(sample.java:66)
at twitter.sample.main(sample.java:52)
The last two status has same key. I don't know how to insert without duplication and also only one status should be inserted.
Thanks in advance!!!
You should use save() method.
save() - Update an existing document or insert a document depending on the parameter.
I am using a Java driver to run some mongo text searches.
An example of my previous code is (where values is a String passed in):
DBCollection coll = db.getCollection("testCollection");
//create the basic object
DBObject searchCmd = new BasicDBObject();
//create the search cmd
searchCmd.put("text", "testCollection"); // the name of the collection (string)
// define the search word
searchCmd.put("search", value); // the term to search for (string)
// define the return values
searchCmd.put("project", new BasicDBObject("score", 1).append("name", 1).append("path", 0).append("_id", 0));
// get the results
BasicDBObject commandResult = db.command(searchCmd);
// Just out the results key
BasicDBList results = (BasicDBList) commandResult.get("results");
then I loop over the "results" and I get for each it score by
// Get the number ii
BasicDBObject element = (BasicDBObject) results.get(ii);
// Now get the score
double score = (double) element.get("score");
I want to upgrade to use find since that seems the way 2.6 and later prefers it. So far I have:
DBCollection coll = db.getCollection("testCollection");
BasicDBObject query = new BasicDBObject();
query.append("$text", new BasicDBObject("$search", value));
DBCursor cursor = coll.find(query);
However, I am not sure how to get the score.
I tried doing something like:
query.append("score", new BasicDBObject("$meta", "textScore"));
But this does not work. I would like to be able to get the name and the score so that I can then insert them into a new collection that will also hold the score.
I can get the name easily by:
while (cursor.hasNext())
{
DBObject next = cursor.next();
String name = next.get("name").toString();
}
But how do I get the score?
I found this interesting page: http://api.mongodb.org/java/current/
it appears that find can take a second DBObject which has the fields.
I created a new object:
BasicDBObject fields = new BasicDBObject();
fields.append("score", new BasicDBObject("$meta", "textScore"));
and I am calling find using:
DBCursor cursor = coll.find(query, fields);
and now I can get the score the same way I can get the name.