Error while retrieving data by Id(hashKey) of a dynamoDb table - java

I am trying to fetch the data from my DynamoDB table based on the Id(HashKey).
Association.java
#DynamoDBTable(tableName = "Association")
public class Association {
private String id;
private String name;
private String adminName;
private String email;
private String url;
private String contactNumber;
private String password;
public Association() { }
public Association(String name, String adminName, String email, String url,
String contactNumber, String password) {
this.name = name;
this.adminName = adminName;
this.email = email;
this.url = url;
this.contactNumber = contactNumber;
this.password = password;
}
public Association(String id, String name, String adminName, String email, String url,
String contactNumber, String password) {
this.id = id;
this.name = name;
this.adminName = adminName;
this.email = email;
this.url = url;
this.contactNumber = contactNumber;
this.password = password;
}
#DynamoDBHashKey(attributeName = "Id")
#DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute(attributeName="Name")
public String getName() { return name; }
public void setName(String name) { this.name = name; }
#DynamoDBAttribute(attributeName="AdminName")
public String getAdminName() { return adminName; }
public void setAdminName(String adminName) { this.adminName = adminName; }
#DynamoDBAttribute(attributeName="Email")
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
#DynamoDBAttribute(attributeName="Url")
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
#DynamoDBAttribute(attributeName="ContactNumber")
public String getContactNumber() { return contactNumber; }
public void setContactNumber(String contactNumber) { this.contactNumber = contactNumber; }
#DynamoDBAttribute(attributeName="Password")
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
AssociationRepository.java:-
private AmazonDynamoDBClient getDynamoDBClient(){
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
client.setRegion(Region.getRegion(REGION));
client.setEndpoint(EndPoint);
return client;
}
public Association fetchById(String id) {
DynamoDBConfig dynamoDBConfig = new DynamoDBConfig();
DynamoDBMapper mapper = new DynamoDBMapper(getDBClient());
Association association = new Association();
association.setId(id);
Association scanResult = null;
try {
scanResult = mapper.load(association);
}
catch (Exception exception){
throw exception;
}
return scanResult;
}
Invoking fetchById("123"). Where "123" is an existing Id of the table It throws the below error to me:-
{
"errorMessage": "The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: IT6U9BJ0RAJUDPMLGGR67C542VVV4KQNSO5AEMVJF66Q9ASUAAJG)",
"errorType": "com.amazonaws.AmazonServiceException",
"stackTrace": [
"com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1305)",
"com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:852)",
DYNAMODB TABLE DETAILS:-
I have searched the AWS docs for this but could not find any solution that fixes this.Does anyone of you ever faced this issue?

If you realize, you defined Name as your partition key. However on code, you are trying to load an item by the attribute Id.
That's not possible as DynamoDB only allows you to load an item by its primary key, which in your case is only the partition key (the attribute Name).
So you have to modify either the table to set Id as partition key, or create a secondary global index to accomplish that:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html

Related

Getting an SQL syntax error doesn't when trying to do GET REQUEST

Hello I'm trying to display the Student data with his corresponding subject based on the subject_id foreign key and displaying the result on GET REQUEST. I don't know how I need to rewrite the SQL command to remove the error. Here is the Error:
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=3' at line 1Retrieve not successful
Here is my DB schema:
Here is my code:
public ArrayList<Object> getStudentSubject(int id) throws Exception {
Connection connection = null;
ArrayList<Student> data = new ArrayList<>();
ArrayList<Subject> data2=new ArrayList<>();
ArrayList<Object> data3 = new ArrayList<>();
try {
connection = new MysqlDbConnectionService().getConnection();
String select ="SELECT student.user_id, student.username, student.password, student.fullname,student.email, subject.id,subject.name" +
"FROM student INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=?";
PreparedStatement ps = connection.prepareStatement(select);
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
Student model = new Student();
Subject model2 = new Subject();
while (rs.next()) {
model.setId(rs.getString("user_id"));
model.setUsername(rs.getString("username"));
model.setPassword(rs.getString("password"));
model.setFullName(rs.getString("fullname"));
model.setEmail(rs.getString("email"));
model2.setId(rs.getInt("id"));
model2.setName(rs.getString("username"));
data.add(model);
data2.add(model2);
data3.add(data);
data3.add(data2);
}
} catch (Exception e) {
System.out.println(e + "Retrieve not successful");
}
return data3;
}
Jersey Code:
#Path("subject/{id}")
#GET
public Response getStudentwithSubject(#PathParam("id") int id) throws Exception {
return Response.ok(new Gson().toJson(studentService.getStudentSubject(id))).build();
}
Student Model:
package com.common.db.domain;
import com.google.gson.annotations.SerializedName;
public class Student {
#SerializedName("id")
private String id;
#SerializedName("username")
private String username;
#SerializedName("password")
private String password;
#SerializedName("fullname")
private String fullName;
#SerializedName("email")
private String email;
public Student()
{
}
public Student(String id, String username, String password, String fullName, String email)
{
super();
this.id=id;
this.username = username;
this.password = password;
this.fullName = fullName;
this.email = email;
}
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 getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Subject Model:
package com.common.db.domain;
import com.google.gson.annotations.SerializedName;
public class Subject {
#SerializedName("id")
private int id;
#SerializedName("name")
private String name;
public Subject() {
this.id = id;
this.name=name;
}
public void setId(int id)
{
this.id=id;
}
public int getId()
{
return id;
}
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
It is a simply wrong SQL formed because of string concatenation, if you observe there is no space between subject.name and FROM student. Add space either after subject.name or before FROM like below.
String select ="SELECT student.user_id, student.username, student.password, student.fullname,student.email, subject.id,subject.name " +
" FROM student INNER JOIN subject ON student.subject_id=subject.id WHERE user_id=?";
Let me know if this helps.

Error while deleting data from dynamoDB table

I am trying to delete the data from my DynamoDB table based on the Id(HashKey).
Association.java
#DynamoDBTable(tableName = "Association")
public class Association {
private String id;
private String name;
private String adminName;
private String email;
private String url;
private String contactNumber;
private String password;
public Association() { }
public Association(String name, String adminName, String email, String url,
String contactNumber, String password) {
this.name = name;
this.adminName = adminName;
this.email = email;
this.url = url;
this.contactNumber = contactNumber;
this.password = password;
}
public Association(String id, String name, String adminName, String email, String url,
String contactNumber, String password) {
this.id = id;
this.name = name;
this.adminName = adminName;
this.email = email;
this.url = url;
this.contactNumber = contactNumber;
this.password = password;
}
#DynamoDBHashKey(attributeName = "Id")
#DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#DynamoDBAttribute(attributeName="Name")
public String getName() { return name; }
public void setName(String name) { this.name = name; }
#DynamoDBAttribute(attributeName="AdminName")
public String getAdminName() { return adminName; }
public void setAdminName(String adminName) { this.adminName = adminName; }
#DynamoDBAttribute(attributeName="Email")
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
#DynamoDBAttribute(attributeName="Url")
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
#DynamoDBAttribute(attributeName="ContactNumber")
public String getContactNumber() { return contactNumber; }
public void setContactNumber(String contactNumber) { this.contactNumber = contactNumber; }
#DynamoDBAttribute(attributeName="Password")
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
AssociationRepository.java:-
private AmazonDynamoDBClient getDynamoDBClient(){
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
client.setRegion(Region.getRegion(REGION));
client.setEndpoint(EndPoint);
return client;
}
private void deleteAssociation(String id) {
try {
DynamoDBConfig dynamoDBConfig = new DynamoDBConfig();
DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBConfig.getDBClient());
Association associationToDelete = new Association();
associationToDelete.setId(id);
// Delete the item.
mapper.delete(associationToDelete);
} catch (Exception exception) {
System.out.println(exception);
throw exception;
}
}
I am getting the below error:-
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: No method annotated with interface com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey for class class Association
I have searched the AWS docs for this but could not find any solution that fixes this.Does anyone of you ever faced this issue?
The issue is the same I mentioned on your other post, in DynamoDB you can’t work an item using attributes which are not the primary key (Partition Key only in your scenario).
Moreover, to delete an item it is mandatory to do it by its primary key, so in your case the attribute Name.
Try to do same operation by setting the name, the error is not very descriptive so maybe there is another underlying issue. However, if you don’t meet above requirement it will never work.

Duplicate Key error while trying to update a field of an Object in MongoDB SpringBoot

I am trying to update a field on my Object and then trying to save it. The code is like this in the controller that will be called.
ApplicationUser user = applicationUserRepository.findByVerificationCode(verificationCode);
if(user != null) {
user.setVerified(true);//trying to change a value in a field
applicationUserRepository.save(user);
return new ResponseEntity<>(user,new HttpHeaders(),HttpStatus.OK);
}
When I try to execute this code, I get this error
E11000 duplicate key error index: myapp.applicationUser.$id dup key: { : 0 };
I am defining Id explicitly in the ApplicationUser class.
My ApplicationUser class is like this
public class ApplicationUser {
#Id
private long id;
private String username;
private String password;
private String name;
private String email;
private String verificationCode;
private boolean verified=false;
private List<Company> boughtCompanies;
public long getId() {
return 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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getVerificationCode() {
return verificationCode;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}
public List<Company> getBoughtCompanies() {
return boughtCompanies;
}
public void setBoughtCompanies(List<Company> boughtCompanies) {
this.boughtCompanies = boughtCompanies;
}
public boolean isVerified() {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
}
What am I doing wrong here or how should I procced? Thanks.
you try to insert an existant user with the same id
function insert i think you should change it with funcion of update
You didnt use the setter of your ID so you need to put it as auto increment
public class ApplicationUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
private String password;
private String name;
private String email;
private String verificationCode;
private boolean verified=false;
private List<Company> boughtCompanies;
public long getId() {
return 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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getVerificationCode() {
return verificationCode;
}
public void setVerificationCode(String verificationCode) {
this.verificationCode = verificationCode;
}
public List<Company> getBoughtCompanies() {
return boughtCompanies;
}
public void setBoughtCompanies(List<Company> boughtCompanies) {
this.boughtCompanies = boughtCompanies;
}
public boolean isVerified() {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
}
Edit:
Set the #Id field as String. It is not good to have long values as ID in mongo.
Also as M. Wajdi said you need to add the setter to the id field.
I see that you are performing an update of a document so you should use applicationUserRepository.save() instead of applicationUserRepository.insert(). (Actually, I always use save).
Explanation:
Insert always try to introduce a new object in the database.
The first time you create the ApplicationUser, insert creates the object in the DB and assign it an ID.
But if you read it, update it and try to insert it again, Mongo will understand that you are actually trying to introduce a new object with the same ID (instead of performing an update in that object).
That's why you get that exception, duplicated key.
While choosing long (or any other primitive) as mongo #Id, then you have to cater the id generation, else everytime it will give long default value i.e. 0
For autoincrement sequencing refer, already answered here Auto increment sequence in mongodb using java.
Else make #Id of type String, mongo autogenerates Default Id of hexadeximal type, for more info refer https://docs.mongodb.com/manual/reference/method/ObjectId/

Looping through the entire firebase data

I would like to find the data of all the users and sum of their scores on particular questions and find the highest rank
Now I can walk through the data users data but not through the questions node.
How do read all the data
This is how I have created my POJO :
private String id;
private String name;
private String contact;
private String email;
private String password;
private int score;
private String dob;
private String profession;
private String random;
private String status;
private String fbId;
private UserPuzzleDetails userPuzzleDetails;
public User() {
}
public User(String id, String name, String contact, String email, String password, int score,
String dob, String profession, String random, String status, String facebookid, UserPuzzleDetails userPuzzleDetails1) {
this.id = id;
this.name = name;
this.contact = contact;
this.email = email;
this.password = password;
this.score = score;
this.dob = dob;
this.profession = profession;
this.random = random;
this.status = status;
this.fbId = facebookid;
this.userPuzzleDetails = userPuzzleDetails1;
}
public User(String id, String name, String contact, String email, String password, int score,
String dob, String profession, String random, String status, String facebookid) {
this.id = id;
this.name = name;
this.contact = contact;
this.email = email;
this.password = password;
this.score = score;
this.dob = dob;
this.profession = profession;
this.random = random;
this.status = status;
this.fbId = facebookid;
}
public User(String name) {
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 String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getContact() {
return contact;
}
public String getDob() {
return dob;
}
public String getProfession() {
return profession;
}
public String getRandom() {
return random;
}
public UserPuzzleDetails getUserPuzzleDetails() {
return userPuzzleDetails;
}
public void setUserPuzzleDetails(UserPuzzleDetails questions) {
this.userPuzzleDetails = questions;
}
public String getStatus() {
return status;
}
public String getFbId() {
return fbId;
}
public void setFbId(String fbId) {
this.fbId = fbId;
}
Now I have used this function to retrieve the data but it is not logging.
How should I go by this data iterate through it.
private void getAllRank() {
final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("users");
final Query query = databaseReference.orderByChild("score").limitToLast(10);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userlist = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
User score = postSnapshot.getValue(User.class);
userlist.add(new User(score.getId(), score.getName(), score.getContact(), score.getEmail(),
score.getPassword(), score.getScore(), score.getProfession(), score.getDob(), score.getRandom(), score.getStatus(), score.getFbId(),score.getUserPuzzleDetails()));
Log.e(TAG, "onDataChange: "+userlist );
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

Spring data Mongo DB retrieving data : #Document VO returns null

I am trying to retrieve data from mongodb via spring framework.
At first I made return type Map<String, Object>, but I decided to change to User value object.
Below is the class for User VO
#Document(collection = "user")
public class User {
#Id
#Field(value="id")
private String id;
#Field(value="name")
private String name;
#Field(value="password")
private String password;
#Field(value="professional")
private String professional;
#Field(value="email")
private String email;
#Field(value="gravatar")
private String gravatar;
#PersistenceConstructor
public User(String id, String name, String password, String professional, String email, String gravatar) {
super();
this.id = id;
this.name = name;
this.password = password;
this.professional = professional;
this.email = email;
this.gravatar = gravatar;
}
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGravatar() {
return gravatar;
}
public void setGravatar(String gravatar) {
this.gravatar = gravatar;
}
};
and Here is #repository to retrieve data
#Repository
public class MongoMemberDao implements CommonDao<String, Map<String, Object>, Exception> {
#Autowired
MongoTemplate template;
final String COLLECTION_NAME = "user";
#SuppressWarnings("unchecked")
#Override
public Map<String, Object> read(String key) throws Exception {
Query findQuery = new Query();
findQuery.addCriteria(Criteria.where("id").is(key));
return template.findOne(findQuery, Map.class, COLLECTION_NAME);
}
public User readByDocument(String id) throws Exception {
Query findOneQuery = new Query();
findOneQuery.addCriteria(Criteria.where("id").is(id));
return template.findOne(findOneQuery, User.class, COLLECTION_NAME);
}
};
read method returns fine, but readByDocument does not(returns null not User instance). I read official document. But I do not get any clue of it.
FYI, The parameter Query looks same for both.
Query: { "id" : "system"}, Fields: null, Sort: null
I want to know why readByDocument returns null
Thanks.
---- Edit
Follow is my Database Config
#Configuration
public class MongoConfig extends AbstractMongoConfiguration {
private final String MONGO_URL = "127.0.0.1";
private final Integer MONGO_PORT = 27017;
#Override
protected String getDatabaseName() {
return "tfarm";
}
#Override
// #Bean
public Mongo mongo() throws Exception {
return new MongoClient(MONGO_URL, MONGO_PORT);
}
}
And I added this to WebApplictaionInitializer implement.
For current solution
I found follow on official site
A field annotated with #Id (org.springframework.data.annotation.Id)
will be mapped to the _id field.
A field without an annotation but named id will be mapped to the _id
field.
The default field name for identifiers is _id and can be customized
via the #Field annotation.
So I changed my VO like...
#Document(collection = "user")
public class User {
#Id
private ObjectId _id;
#Field(value="id")
private String id;
#Field(value="name")
private String name;
#Field(value="password")
private String password;
#Field(value="professional")
private String professional;
#Field(value="email")
private String email;
#Field(value="gravatar")
private String gravatar;
#PersistenceConstructor
public User(String id, String name, String password, String professional, String email, String gravatar) {
super();
this.id = id;
this.name = name;
this.password = password;
this.professional = professional;
this.email = email;
this.gravatar = gravatar;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public ObjectId get_id() {
return _id;
}
public void set_id(ObjectId _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getProfessional() {
return professional;
}
public void setProfessional(String professional) {
this.professional = professional;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGravatar() {
return gravatar;
}
public void setGravatar(String gravatar) {
this.gravatar = gravatar;
}
};
Added ObjectId. In alternative, just removing #Id annotation works fine too. However
#Id
#Field(value="id")
String id;
will not work. Thanks for help.

Categories