Update specific attributes with DynamoDBMapper in java - amazon-dynamodb

I want to update only the specific attributes of the item using DynamoDBMapper.
For example, I have a User table with attributes viz., id, name, address.
#Data
#DynamoDBTable(tableName = "Users")
public class User {
#DynamoDBHashKey
#DynamoDBGeneratedUuid(DynamoDBAutoGenerateStrategy.CREATE)
private String id;
#DynamoDBAttribute
private String name;
#DynamoDBAttribute
private Address address;
}
I want to update only the address attribute and not the other fields (selective update).
I could find a sample example by using UpdateItemSpec but couldn't find it for DynamoDBMapper.
With UpdateItemSpec, I can use withUpdateExpression() to define update expression.
More details can be found here.
Is there any way, to achieve the same with DynamoDBMapper?

Use the UPDATE_SKIP_NULL_ATTRIBUTES SaveBehavior
More details on: https://aws.amazon.com/blogs/developer/using-the-savebehavior-configuration-for-the-dynamodbmapper/
Add the SaveBehavior to your save operation and keep fields other than id and address null:
mapper.save(user, new DynamoDBMapperConfig(SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES));

Related

Storing a value globally across all pages

This is an ASP.NET Forms project. When user enters his/her user name and password (in the Login page) I want to save the user name such that it can be retrieved in the code of any page of the project. I know that I can do it via a session variable.
But is it possible to create a Static Public class with Get Set and store the value there and retrieve it using this class?
If you are using master page create a hidden field in that store that information in that hidden value so you can access in any page where you are using that master page.
Static classes are shared across instances/sessions in your app, which means you could end up with something akin to race conditions; for instance, a request from User_A could read values that were set in your static class by User_B. (see this SO answer)
Shooting from the hip, it might be easier to write a wrapper/abstraction class for your users' info that makes accessing their details easier. Something like:
public class UserDetails{
public string Name;
public string Age;
public string Gender;
public UserDetails(HttpContext context){
this.Name = context.User.Identity.Name;
this.Age = ...;
this.Gender = ...;
// Alternatively, you could perform your own data access to
// get/set these details. It depends on how you're storing your
// users' info.
}
}
Then in your code behind...
UserDetails userDetails = new UserDetails(context.Current);
Response.Write(userDetails.Name); // user's name
Response.Write(userDetails.Age); // user's age
...

csv to pojo with another pojo

Orgnization{
private String name;
private String uniqueId;
private boolean selfRegEnabled;
private List<Address> addrList;
public void setAddress(Address a){..}
public void setName(String name){..}
}
Addess{
private String type;
private String line1;
private String line2;
private String line3;
private String city;
private String state;
private String zip;
private String country;
}
CSV Header Columns are as below
System.UniqueID,Name,EnableSelf-Registration,Addr1.Type,Addr1.Line1,Addr1.Line2,Addr1.Line3,Addr1.City,Addr1.State,Addr1.Zip,Addr1.Country,Addr2.Type,Addr2.Line1,Addr2.Line2,Addr2.Line3,Addr2.City,Addr2.State,Addr2.Zip,Addr2.Country,Addr3.Type,Addr3.Line1,Addr3.Line2,Addr3.Line3,Addr3.City,Addr3.State,Addr3.Zip,Addr3.Country
My question might be related to below link
OpenCSV CSV to JavaBean
I didn't see that thread has a proper answer (I am not sure if I miss any from that thread)
Can we achieve same thing with any of the existing csv libraries such as supercsv, opencsv?
If I am using supercsv - can I map System.UniqueID column of csv to systemUniqueID property of my bean
You can certainly do this with Super CSV using CsvDozerBeanReader. See this example on the website.
It's also explained in a bit more detail on this SO answer.
You may also be interested in this recent question, as it demonstrates the different ways to achieve deep/indexed mapping with Super CSV (with and without using Dozer).
Following the CsvDozerBeanReader example on the website, to read the CSV from your question you would use a field mapping of:
final String[] fieldMapping = new String[]{
"uniqueId",
"name",
"selfRegEnabled",
"addrList[0].type",
"addrList[0].line1",
"addrList[0].line2",
"addrList[0].line3",
"addrList[0].city",
"addrList[0].state",
"addrList[0].zip",
"addrList[0].country",
"addrList[1].type",
"addrList[1].line1",
"addrList[1].line2",
"addrList[1].line3",
"addrList[1].city",
"addrList[1].state",
"addrList[1].zip",
"addrList[1].country",
"addrList[2].type",
"addrList[2].line1",
"addrList[2].line2",
"addrList[2].line3",
"addrList[2].city",
"addrList[2].state",
"addrList[2].zip",
"addrList[2].country"
};
Also, because the selfRegEnabled field is a boolean, you'll need to use cell processors to transform the String value into a Boolean - to do this you'd use the ParseBool processor.

Objectify How to Assign value to Parent Key

I'm getting my feet wet with persistence and Objectify. I'd like some guidance on assigning a Parent key. My specific questions are in all caps. Thanks.
(The sample model below contains an AppUser and a Video. The idea is like YouTube; a user creates videos that belong to him/her.)
#Entity
class Video{
// QUESTION 1: SHOULD THIS CLASS HAVE ONLY 1 KEY FIELD IF I WANT A
PARENT RELATIONSHIP WITH AppUser, AND TYPE IS Key<AppUser> ?
#Parent Key<AppUser> owner;
#Id private Long id;
protected Video(){}
protected Video(User u){ // GAE User object
AppUser au = ofy().load().type(AppUser.class).filter("userId",u.getUserId()).first().get();
// QUESTION 2: WHICH WAY IS RIGHT (TO ASSIGN PARENT KEY)?
this.owner = Key.create(au.getKey(),AppUser.class,au.getId());
// or:
// owner = au.getKey();
// or:
// owner = au;
}
}
#Entity
public class AppUser {
#Id private String userId;
// QUESTION 3: DO ALL CLASSES REQUIRE A KEY FIELD?
private Key<AppUser> key;
protected AppUser(){}
protected AppUser(User u){// GAE User object
this.userId = u.getUserId();
}
public String getId(){
return userId;
}
public Key<AppUser> getKey(){
// QUESTION 4: IS THIS THE CORRECT WAY TO RETURN THE KEY?
// WOULD THAT IMPLY I NEED TO EXPLICITLY ASSIGN A VALUE TO FIELD key?
return this.key;
// THE ALTERNATIVE WOULD BE TO CREATE A KEY
AND RETURN IT RIGHT? (THEN I CAN EXCLUDE FIELD key?)
// return Key.create(AppUser.class, userId);
}
}
Answering my own question based on further knowledge:
Normally if a parent relationship is desired, one Key is fine. I can't see why another Key field would be required.
I don't think there's 1 right way to assign a value to the #Parent Key. Using this seems to work:
this.parent = Key.create(instanceOfParent);
All classes do not REQUIRE a key field. Use when needed.
There's no one right way to return a Key, both examples could work.

How does versioning work with Flex remote objects and AMF?

Suppose I use the [RemoteClass] tag to endow a custom Flex class with serialization intelligence.
What happens when I need to change my object (add a new field, remove a field, rename a field, etc)?
Is there a design pattern for handling this in an elegant way?
Your best bet is to do code generation against your backend classes to generation ActionScript counterparts for them. If you generate a base class with all of your object properties and then create a subclass for it which is never modified, you can still add custom code while regenerating only the parts of your class that change. Example:
java:
public class User {
public Long id;
public String firstName;
public String lastName;
}
as3:
public class UserBase {
public var id : Number;
public var firstName : String;
public var lastName : String;
}
[Bindable] [RemoteClass(...)]
public class User extends UserBase {
public function getFullName() : String {
return firstName + " " + lastName;
}
}
Check out the Granite Data Services project for Java -> AS3 code generation.
http://www.graniteds.org
Adding or removing generally works.
You'll get runtime warnings in your trace about properties either being missing or not found, but any data that is transferred and has a place to go will still get there. You need to keep this in mind while developing as not all your fields might have valid data.
Changing types, doesn't work so well and will often result in run time exceptions.
I like to use explicit data transfer objects and not to persist my actual data model that's used throughout the app. Then your translation from DTO->Model can take version differences into account.

problem with asp.net gridview

I have problem with gridview deleting.I have table name Doctor with
Id,Name,Address,Phone.Id is auto generated field.After adding data
when i am displaying in gridview then if delete any id from gridview
Again then if i add any new details from the form its starting from
the new number.I mean if i delete the last id no 5 then again if i
add any new doctor its taking id value 6 not from 5.My query is it
should start again from 5.Here is my code.Pls help me.
public class Doctor
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
}
public static class DoctorDataLayer
{
public static void AddDoctor(Doctor doctor)
{
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; // JohannesH: Changed from .ToString() to .ConnectionString
using(var connection = new SqlConnection(connectionString))
{
using (var command = new SqlCommand("insert into doctor values(#name,#address,#phone)", connection))
{
command.Parameters.AddWithValue("#name", doctor.Name);
command.Parameters.AddWithValue("#address", doctor.Address);
command.Parameters.AddWithValue("#phone", doctor.Phone);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
}
}
}
public static class DoctorBusinessLayer
{
public static void CreateDoctor(string name, string address, string phone)
{
DoctorDataLayer.AddDoctor(new Doctor {Name = name, Address = address, Phone = phone});
}
}
This is perfectly normal database behaviour and has nothing to do with your GridView. If you have an issue with gaps in autogenerated (identity) columns, either use your own logic to generate unique ID's or use custom SQL scripts to check for gaps in Identity values and fill those gaps.
Example B in the Transact-SQL reference shows a way to do just this.
So the Id is created by the database (autonumber). When id 5 is used it's used up. This is normal behavior.
As other have noted, if this is an autogenerated ID from the DB then once it is used it will not be regenerated, each ID is unique regardless if the data still exists or not. If IDs were recycled you could get into issues with foreign references that may have pointed to the old item with that ID and now would point to a new different record with the reused ID.
Typically you don't expose the IDs to the user anyway so it is a non issue.
You shouldn't depend on autogenerated ids sequences being ordered or not having gaps. As others have noted, the behavior you are seeing is perfectly normal behavior for an autogenerated id and to make it otherwise you'll need to jump through a lot of hoops. If you need the ids to be ordered by the insertion sequence, you should put in an autogenerated date/time field and then select the data ordered by that field (and index it). That way if you ever decide to switch from a numeric id to a GUID or some other id format in which the sort order is different than the insertion order your data will still be ordered correctly. If you need to have a "place order" for each, generate that automatically (say a rownumber) as you are selecting ordered by date. That way you will still have strict numerical ordering even if records get deleted later.

Resources