I have a pojo class as follows.
public class Person {
private String name;
private Address address;
public String getName() { ... }
public Address getAddress() { ... } //Address bean
public void setName() { ... }
public void setAddress() { ... }
}
Get data from DB (json converted to above POJO)
Show it to user
User changes his Address
Saving back to DB
This is what currently happening. Now I am trying to make a delta of user made changes Vs database changes. (which is address alone)
I need to know what user has changed. This is for making an audit log.
In this case it's address. That new address should be put into the new Person-POJO class (with all other setters as NULL).
So that I would get
address {
-- new address
},
name {
-- NULL //or no need to have "name" as address only changed
}
What would be the best method to achieve this ?
I know there are few libraries with with we can compare beans with some comparators. But it will just compare, will not provide the changed part alone. If there is any, please provide a link.
I got an idea from https://stackoverflow.com/a/472637/2086966 answer. Trying to do as this method.
Related
So I have an object Person let's say, with the following fields (for simplicity)
class Person{
String name
List<Address> addressList
}
class Address{
String streetNo
}
This would be the way to go usually, but now that im working with grails I thought it should be the following:
class Person{
String name
List addresses
static hasMany = [addresses: Address]
}
class Address{
String streetNo
static belongsTo = Person
}
I'm receiving the data from an HTTP call and im trying to save it:
def persons = response.getAt("response").getAt("persons").collect()
persons.forEach({ current ->
def person = new Person(current)
person.save()
})
The parsing is working properly as when I check the person object before saving it, I can see the address being added correctly (at first NOT saved and without an ID but after the save, an ID is added)
Now when I want to fetch all persons, I do a basic
respond Person.list()
I get all the details correct but the address I get only the address IDs so for example:
{
id: 1,
name: foo,
addresses:[
{id:1},{id:2}
]
}
But what I want here is the actual address object not its id!
Also I noticed that after retrieving the Person list a couple of times the addresses list gets empty and I end up with addresses:[]
I tried to remove the hasMany and go back to the list but it didn't work either, I went through the official documentation but nothing points out more than what I already tried and/or mentioned
There are several approaches to render your hasMany refs:
turn lazy-loading for addresses off:
class Person{
String name
List addresses
static hasMany = [addresses: Address]
static mapping = {
addresses lazy: false
}
}
as you rather want the addresses to behave as embedded objects.
You can resolve each address in a person by explicitly call it's props:
def list = Person.list()
list*.addresses*.streetNo
respond list
use Jackson-annotations
#JsonAutoDetect(fieldVisibility = Visibility.PUBLIC_ONLY) // either for the class
class Person{
String name
#JsonProperty // or for each prop
List addresses
static hasMany = [addresses: Address]
}
UPDATE
If you use mongo, you can use embedded to its full strength:
class Person{
String name
List<Address> addresses
static embedded = [ 'addresses' ]
}
class Address{
String streetNo
}
in Person try to add
static mapping { fetch: 'join' }
So I am creating a chat app for android and I'm using Java and I need some help wrapping my head around some things. Whenever the user first registers, I am creating a new object of a class named User. When they enter the next layout, I need to access that objects data.
public class User {
public String username;
public User() {}
public User(String username) {
this.username = username;
}
public String getUsername(){
return username;
}
}
This is my User class. When they send a message, I need to be able to grab their username from this User object from an entirely different method without passing the object through a parameter. I can't seem to wrap my head around how to access their information and none of my methods seem to work. Any help is appreciated
If you do
User myUser = new User();
the variable myUser contains a reference to the newly created object. You must keep this reference around in order to later access the object. How exactly you do this depends on the logic of your program. Sometimes you would keep it in a field of another object or pass it around as parameter. For example
un = myUser.getUsername();
or
void myMethod(User theUser) {
...
String un = theUser.getUsername();
}
...
// call the method passing the user reference
myMethod(myUser);
in the main class make the data object... static
public static Model obj;
obj= new Model();
then from other class access it with your class name
example
main.obj;
I solved this issue by just using SharedPreferences. I stored the username associated with the key of each user. This way, I can always search the username for each user.
As the title says....
I want to build a POJO with four field variables and at certain runtime events create an instance of this POJO with access to possibly maybe two or three of the fields.
public class Category implements Serializable {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Lets say I create a new Category object but I only want to be able to have access to the name field during runtime. Is there a design pattern I can use to achieve this? I thought about the strategy pattern and looked at the builder but I am still confused if I can do this in java.
Basically the overall goal is to grab an object from a database and return it as a JSON response in jax rs. But sometimes I dont want a complete object returned but only lets say halve of the object to be accessible at during certain runtime events. My apologies if this seems like a dumb question but I know what I want to do but just don't know the best way.
I have the same problem with you, and my project was used springmvc,and the json tool is jackson.With the problem solved, I just use #JsonIgnore.For more details,just read jackson-how-to-prevent-field-serialization
So someone correct me if I am wrong or see a better option than this...with alot of objects this can be alot of extra code for serialization and deserialization...Jackson Provisions is what I need. I can use the annotation #JsonView(DummyClass.class) on the field variable. I will accept this a the best answer in a day or two unless someone else posts a better response.
// View definitions:
class Views {
static class Public { }
static class ExtendedPublic extends PublicView { }
static class Internal extends ExtendedPublicView { }
}
public class Bean {
// Name is public
#JsonView(Views.Public.class) String name;
// Address semi-public
#JsonView(Views.ExtendPublic.class) Address address;
// SSN only for internal usage
#JsonView(Views.Internal.class) SocialSecNumber ssn;
}
With such view definitions, serialization would be done like so:
// short-cut:
objectMapper.writeValueUsingView(out, beanInstance, ViewsPublic.class);
// or fully exploded:
objectMapper.getSerializationConfig().setSerializationView(Views.Public.class);
// (note: can also pre-construct config object with 'mapper.copySerializationConfig'; reuse)
objectMapper.writeValue(out, beanInstance); // will use active view set via Config
// or, starting with 1.5, more convenient (ObjectWriter is reusable too)
objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
This information was pulled from http://wiki.fasterxml.com/JacksonJsonViews
with jackson 2.3, I can do this with JAX-RS
public class Resource {
#JsonView(Views.Public.class)
#GET
#Produces(MediaType.APPLICATION_JSON )
public List<Object> getElements() {
...
return someResultList;
}
}
Consider following model:
public class Contact {
#Required
public String name;
#Valid
public List<Information> informations;
}
public static class Information {
public String securedField;
#Required
public String email;
#Valid
public List<Phone> phones;
public static class Phone {
#Required
#Pattern(value = "[0-9.+]+", message = "A valid phone number is required")
public String number;
}
}
}
I don't want Information securedField to be affected by mass assignment vulnerability. So i decided to set array of allowedFields for Contact Form.
As i know, play forms are based on Spring DataBinder, so is it possible to handle collection fields? I don't want to write smth like:
name
informations[0].email
informations[0].phones*
informations[1].email
informations[1].phones*
etc
Following doesn't work:
name
informations.email
informations.phones*
Should i extend existing Spring DataBinder and Form classes and override bind method in this case?
Here's an arguably simpler solution. How about defining an extra constraint that will trigger a validation failure if the POST data contains any informations[%d].securedField values?
import javax.validation.constraints.Null;
public static class Information {
#Null
public String securedField;
...
}
I think that this way you can call the default bindFromRequest method instead of the one that accepts a whitelist of form field names, and still be protected against a mass assignment attack.
One shortcoming with this approach admittedly is that it would ultimately leak the names of your internal fields in the event of a concerted mass assignment attack. However if they had fairly bland, meaningless names such as securedField (no offence intended!), I'm not sure how this information could be exploited by an attacker.
Edit
If you want to allow assignment to the field based on the current user type, maybe bean validation groups could help:
import javax.validation.constraints.Null;
public class Contact {
public interface Administrator {}
public interface User {}
...
public class Information {
#Null(groups = User.class)
public String securedField;
...
}
}
Controller code
...
final Form<Contact> contactForm;
if (currentUser.isAdministrator()) {
contactForm = form(Contact.class, Administrator.class).bindFromRequest();
} else {
contactForm = form(Contact.class, User.class).bindFromRequest();
}
...
If I understand your question correctly, you can use the following patterns to whitelist nested collection fields:
informations[*].email
informations[*].phones[*].*
i.e.
form.bindFromRequest("name", "informations[*].email", "informations[*].phones[*].*");
Let's say I have a method in java, which looks up a user in a database and returns their address and the team they are on.
I want to return both values from the method, and don't want to split the method in two because it involves a database call and splitting involves twice the number of calls.
Given typical concerns in a moderate to large software project, what's the best option?
whatGoesHere getUserInfo(String name) {
// query the DB
}
I know the question smells of duplication with existing ones, but each other question had some element that made it different enough from this example that I thought it was worth asking again.
you have some options.
The most OOP it will be create a class to encapsulate those 2 properties, something like that
private class UserInfo {
private Address address;
private Team team;
}
Or if you want a simple solution you can return an array of objects:
Object[] getUserInfo(String name) {
// query the DB
return new Object[]{address,team};
}
Or if you want to expose this method to some library you can have some interface that it will consume those properties, something like this:
class APIClass{
interface UserInfo{
public Address getAddress();
public Team getTeam();
}
UserInfo getUserInfo(String name) {
// query the DB
return new UserInfo(){
public Address getAddress(){ return address; }
public Team getTeam(){ return team; }
};
}
}
cant a map help , A MultivalueMap. Where the key is the user name and the 2 values are the adress and the team name. I am assuming both your Address and team are String variables, You can know more about Multivalue Map here
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/MultiValueMap.html
http://apachecommonstipsandtricks.blogspot.in/2009/01/multi-value-map-values-are-list.html
First model your abstractions, relationships and multiplicity well (see an e.g. below). Then you can model tables accordingly. Once these two steps are performed you can either leverage JPA that can be configured to load your object graph or you write JDBC code and create the graph your self by running a SQL query with proper SQL JOINs.
A User has an Address
A Team can have 1 or more Users (and can a User play for more teams?)
You can return a String array with user name and group name in it . The method looks like :
public String[] getUserInfo(String name) {
String[] result = new String[2];
// query the DB
...
result[0] = userName;
result[1] = groupName;
return result;
}
A common solution to this kind of issue is to create a custom object with as many attributes as the values you want to return.
If you can't create a new class for this, you can use a Map<String, Object>, but this approach is not type-safe.
I thought Guava had a generic Pair class already, but I cannot find it. You can build your own using generics if you're on Java 1.5+.
public class Pair<X,Y>
{
public final X first;
public final Y second;
public Pair(X first, Y second) {
this.first = first;
this.second = second;
}
}
Feel free to make the fields private and add getters. :) Using it is easy:
return new Pair<Address,Team>(address, team);
Update
Apache Commons Lang has Pair. See this SO question for more options.