how to get inserted object id in jongo with mongodb - mongodb

Account entity
public class Account
{
#MongoObjectId
private String _id;
private String name;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class JongoExample {<br>
MongoClient mongoClient = new MongoClient(); // code to connect with database
DB db = mongoClient.getDB("kommboxj");
Jongo jongo = new Jongo(db);<br>
MongoCollection accountCollection = jongo.getCollection("account");
Account account = new Account();<br>
account.setName("rks");<br>
String accountIdMongo = (String) accountCollection.insert(account).getUpsertedId();}
Here I found acountIdMongo is null, don't know how to get it, here I want inserted account ObjectId.

For me this helped:
Jongo Starter Project
Based on the above the _id in Color.java would be:
#MongoObjectId
private String _id;
and then in PersistenceHandler.java in the insert method the Object returned would contain the inserted object in the Mongo collection with _id populated.
public static Object insert(MongoCollection mongoCollection, Method method, Object[] args) throws Throwable {
final Iterable<Parameter> params = Reflection.params(method, args);
final Parameter parameter = params.iterator().next();
Object value = parameter.getValue();
if (value == null)
throw new IllegalArgumentException(parameter.getType().getSimpleName() + " object is null");
mongoCollection.insert(value);
return value;
}

Related

method in ArangoRepository extension class using COLLECT in query annotation to group by and count not working

I have a simple node like this below
#Document("users")
public class User {
#Id // db document field: _key
private String id;
#ArangoId // db document field: _id
private String arangoId;
private String firstName;
private String lastName;
private String country;
public User() {
super();
}
public User(String id) {
this.id = id;
}
public User(String id, String country) {
this.id = id;
this.country = country;
}
// getter & setter
#Override
public String toString() {
return "User [id=" + id + ", name=" + firstName + ", surname=" + lastName + "]";
}
public String getId() {
return id;
}
}
here is the repository class but the method getListOfCountryAndNumUsers returns null even though i have inserted users with different countries into the database.
public interface UserRepository extends ArangoRepository<User, String> {
#Query("FOR u IN users COLLECT country = u.country WITH COUNT INTO length RETURN
{\"country\" : country, \"count\" : length }")
Iterable<CountryAndNumUsers> getListOfCountryAndNumUsers();
}
I think the problem could be with the the syntax of my query in the query annotation. I didnt see any direct example of using collect operation in the spring data arango db part of arangodb documentation here but I saw the collect operation in the section "high level operations" of arangoDb documentation here
Please Help. Thanks. !
So I discovered my error. It was in a class I didn't add in the question. That is the class for the return object of the method getListOfCountryAndNumUsers()
i.e class CountryAndNumUsers.
public class CountryAndNumUsers {
private String country;
private Integer numberOfUsers;
public CountryAndNumUsers(String country, Integer numberOfUsers) {
this.country = country;
this.numberOfUsers = numberOfUsers;
}
public String getCountry() {
return country;
}
public Integer getNumberOfUsers() {
return numberOfUsers;
}
}
so there was a mapping mismatch since the query returns an object with different field names. I changed the query to this below so that it matches
#Query("FOR u IN users COLLECT country = u.country WITH COUNT INTO length RETURN {\"country\" : country, \"numberOfUsers\" : length }")

Exception when selecting specific columns using Hibernate and Spring Data JPA

I have a table that has a bytea column (named 'pdf') and I don't want to always select it, specially when I'm returning a list from the database, due to performance issues.
I use native queries with spring data inside the repository to solve these types of situations before (when I used eclipselink), but with Hibernate, if I don't write all the columns in the query, it throws an exception.
For test purposes, I'm trying to select only the id from the User and I still get the exception.
Example: "SELET user.id FROM user WHERE user.id = '1'"
It throws an exception saying that it did not find name in the ResultSet, if I put name in the SQL, it then says age was not found and so on, until I have to write all the columns in the SQL.
Thanks in advance for any help.
What I have tried already:
Updating/Downgrading Hibernate and Spring Data with no luck.
Creating a new entity with only the columns I need, works, but it's a messy solution for me.
Maybe the problem is the combination of the frameworks I use and the way I use them, if someone wants, I could try to upload my whole project structure.
My code:
Entity
#Entity
#Table(name = "user", schema = "portal")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "pdf")
private byte[] pdf;
#Column(name = "name")
private String name;
#Column(name = "age")
private Integer age;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public byte[] getPdf() {
return pdf;
}
public void setPdf(byte[] pdf) {
this.pdf = pdf;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Anexo)) {
return false;
}
Anexo other = (Anexo) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "br.gov.to.secad.portal.domain.User[ id=" + id + " ]";
}
}
Service
#Service
#Transactional(readOnly = true)
public class UserService implements Serializable {
private static final long serialVersionUID = 1L;
#Autowired
private IUserRepository userRepository;
public UserService() {
}
public User findOne() {
return userRepository.findOneSQL();
}
}
Repository
public interface IUserRepository extends JpaRepository<User, Serializable>, JpaSpecificationExecutor {
#Query(value = "SELECT user.id FROM user WHERE user.id = '1'", nativeQuery = true)
public User findOneSQL();
}
The exception:
org.postgresql.util.PSQLException: The column name name was not found in this ResultSet.
Solution
The solution is using an array of Object when I want to select anything less than what I've mapped on my Entity class, thats the limitation of Hibernate that I now understand.
So basically, the method will return Object[] and then I can iterate each position and instantiate a new entity of User with these values.
Example:
#Query(value = "SELECT user.id FROM user WHERE user.id = '1'", nativeQuery = true)
public Object[] findOneSQL();
I have faced the same problem, I know it is late but well there is a solution that I found elegant.
By the Spring documentation you can declare an interface and from here take the fields you want, in my case it has been something similar to this.
The interface to minimize the fields:
public interface CountryMinify {
String getName();
String getNameTranslation();
}
And my JpaRepository
public interface PlanetRepository extends JpaRepository<Planet, Long> {
#Query(value = "select p.name_country as name, p.name_country_translation as nameTranslation from vm_planet p where gid = ?1", nativeQuery = true)
CountryMinify findByCode(String codeCountry);
}
Keep in mind that the columns should be called the same as gos getter. For example: column name_country -> AS name and the getter of the interface is getName()
Try this
#Query(value = "SELECT user.id FROM user WHERE user.id = '1'", nativeQuery = true)
Integer findOneSQL();
Call the method like so
Integer user = userRepository.findOneSQL();
Edit 1 :
Since you are using native query you wont be able to use Projections which is a great way of accessing only certain entity fields. There is a JIRA ticket which is still under investigation.
Solution
Return List from your repository like so
#Query(value = "SELECT user.id, user.name FROM user WHERE user.id = '1'", nativeQuery = true)
List<Object[]> findOneSQL();
Iterate over the list of Objects and get your specific columns.
List<Object[]> userNative = userRepository.findOneSQL();
for (Object[] obj : userNative) {
System.out.println("User id : " + obj[0]);
System.out.println("User Name : " + obj[1]);
}

update mongodb document using java object

I have one User class like this:
#Document(collection = "users")
public class User {
#Id
private String id;
String username;
String password;
String description;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "User[id=" + id + ", username=" + username + ", password=" + password + ", description"
+ description + "]";
}
}
I am able to perform limited update. Like:
Query searchQuery = new Query(Criteria.where("id").is("shashi"));
mongoDBClient.updateFirst(searchQuery, Update.update("password", "newpassword"), User.class);
Now if I want to update rest other fields(username and description) of User class, I need to call updateFirst method so many times.
I want to avoid this and pass the entire object to updateFirst method. Something like:
mongoDBClient.updateFirst(searchQuery, Update.update(userObject), User.class);
Basically, I want to edit all/multiple fields in one call using java POJO object. How I can achieve this?
Edit/All multiple fields in one call using java POJO object, can be done as shown below
1) Query the document which need to be updated --> we get the java object
2) Do all modifications in the java object
3) Save the object
Code:
Query query = new Query();
query.addCriteria(Criteria.where("id").is("shashi"));
User user = mongoOperation.findOne(query, User.class);
//modify the user object with the properties need to be updated
//Modify password and other fields
user.setPassword("newpassword");
user.setDescription("new description");
user.setUsername("NewUserName");
//save the modified object
mongoOperation.save(user);

dropdownchoice with choicerenderer, how to get values

i have problem trying to get some values. this is my situation (wicket)
i have a dropdownchoice study_template, i don't have problem populating the DDC, the problem is when i try to get some value (id or name). this is the code
ChoiceRenderer choiceRenderer = new ChoiceRenderer("name", "id");
study_template = new DropDownChoice( "study_template",new PropertyModel( this, "selectedTemplate" ),template_names , choiceRenderer);
template_names is a list< SelectOption > with the values obtain from a DB. this works OK.
this is the class that i use to populate the DDC
public class SelectOption implements java.io.Serializable {
private long id;
private String name;
public SelectOption(long id, String name ) {
this.id = id; this.name=name;
}
public long getId()
{return id; }
public String getName()
{return name; }
}
normally i can get the value with study_template.getModelObject(), but in this case it doesn't work, i don't have any ideas about to obtain the id and the name , i know that i need GETID() and GETNAME(), but i don't know how to use it, any help will be appreciated
You could use something as below:
public class SpikePage extends WebPage {
class Person {
String id;
String name;
public Person(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public SpikePage() {
Person employee = new Person("E001", "ABC");
Person manager = new Person("E002", "XYZ");
List personList = new ArrayList(2);
personList.add(employee);
personList.add(manager);
Form form = new Form("form");
final DropDownChoice personDropDownChoice = new DropDownChoice("person", new ArrayList(personList), new IChoiceRenderer() {
#Override
public Object getDisplayValue(Person object) {
return object.getId().concat("-").concat(object.getName());
}
#Override
public String getIdValue(Person object, int index) {
return object.getId();
}
});
personDropDownChoice.setOutputMarkupId(true);
personDropDownChoice.setNullValid(false);
form.add(personDropDownChoice);
final Label label = new Label("name");
label.setOutputMarkupId(true);
form.add(label);
personDropDownChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
#Override
protected void onUpdate(AjaxRequestTarget target) {
Person selectedPerson = personDropDownChoice.getModelObject();
label.setDefaultModelObject("Hi ".concat(selectedPerson.getName()));
target.add(label);
}
});
add(form);
}
}
Thanks for your answer, i already get it work
i use this
private SelectOption selectedTemplate;
and then
selectedTemplate.getId();

MongoDB Java - update a field in a record

I would like to update a field of a record which has been already been stored in the database. How can I achieve that? All of the examples I've come across so far are either in Python/Php or an older version of MongoDB (Java) and the api is not longer current.
Basically I would like to load an object with a particular userId in memory and change its username value. (I'd like to refer you to the code below)
Thank you so much
EDIT
So far I've got the following code:
public class UserDAO {
MongoOperations mongoDb;
public UserDAO(){
mongoDb = MongoDBInstanceFactory.getMongoDBinstance();
}
public User getUserByUsername(String username){
Query searchUserQuery = new Query(Criteria.where("username").is(username));
return mongoDb.findOne(searchUserQuery, User.class);
}
public User getUserById(String id){
Query searchUserQuery = new Query(Criteria.where("id").is(id));
return mongoDb.findOne(searchUserQuery, User.class);
}
public User addUser(String username){
mongoDb.save(new User(username));
return getUserByUsername(username);
}
}
#Document(collection = "users")
public class User {
public User(String username) {
this.username = username;
}
public User() {
}
#Id
private String id;
private String username;
//getter, setter, toString, Constructors
/**
* #return the id
*/
public String getId() {
return id;
}
/**
* #return the username
*/
public String getUsername() {
return username;
}
}
#RequestMapping(value = "/registerUser")
public #ResponseBody
String registerUser(#RequestParam(value = "username") String username, HttpServletResponse response) throws IOException {
sb = new StringBuilder();
user = userDao.getUserByUsername(username);
if (user == null) {
user = userDao.addUser(username);
userQueryPhaseDao.addUserQueryPhase(user.getId(), null, "0");
sb.append("1|").append(user.getId());
response.addCookie(new Cookie("userId", user.getId()));
} else {
sb.append("0|User with that handle already exists!");
}
return sb.toString();
}
Thank you for your time
To change an existing document, use the method DBCollection.update.
The method takes two parameters.
The first parameter tells MongoDB which document to update. It works exactly like find or findOne.
The second is the document that document will be replaced with. When you only want to update a single field and not replace the whole document, you need to use the $set operator.