How to avoid missing setting a field's value in a POJO? - java

I have a POJO which has tens of fields, and I have to set all the fields' values.
How to avoid forgetting to set some field's value?
// POJO
public class Employee {
private Date birthday;
private String firstName;
private String lastName;
private String birthOfPlace;
// ...
// setters and getters
}
// Main class
public class MainClass {
public static void main(String[] args) {
Employee employee = new Employee();
// Call all the setters of Class Employee
employee.setFirstName("Jack");
employee.setLastName("Reed");
employee.setBirthOfPlace("Iceland");
// Oops, forget to call setBirthday()
}
}

As far as I know, there's no silver bullet solution to what you're asking for: at some point, you will have to either add a value to needed fields in your object, or write code that checks if you did it or not.
However, if you want to try anyway, there's a decent approache to making sure the most critical fields are present when needed: constructor parameters.
public Employee(String firstName, String lastName, Date birthday) {
this.firstName = firstName;
this.lastName = lastName;
this.birthday = birthday;
}
As long as you don't implement another constructor in this class, with this code, you'll be forced to provide a first name, last name, and date for each employee, meaning they'll never not be present (unless you pass null, but avoid doing that, it's arguably bad practice). If you need all your fields to be present, you'll need that many matching parameters in your constructor.
An alternative to this is to use an embedded Builder.

Use inner Builder class inside your class with constructor with required parameter(s), e.g. firstName:
public static class Builder {
private String firstName;
private String lastName;
public Builder(String firstName) {
this.firstName= firstName;
}
public Builder lastName(String lastName) {
lastName = lastName;
return this;
}
Make sure you can create an object only through the Builder

Related

Choosing what pojo to use based on the user role on an edit request

So I am wondering what the best way to process an edit request based on a user role.
Say I have the following PostMapping:
#PostMapping(value = "/edit")
public ResponseEntity<String> editIoc(#RequestBody GeneralPojoAllFields editRequest)
the GeneralPojoAllFields looks like this:
public class GeneralPojoAllFields {
private String firstName;
private String lastName;
private String onlyAdminCanEditField;
}
This is the pojo the the admin will be able to use and that will eventually get mapped into the entity class to be saved to the database. However, if we have a regular user who wants to edit it and hypothetically they aren't restricted in the UI would that design work? What I am currently thinking is I would have a user pojo like so:
public class UserPojo {
private String firstName;
private String lastName;
}
After the request mapping comes we check if the user is either regular user or an admin. If it is a regular user we just map the GeneralPojoAllFields to the UserPojo and it wont map over the onlyAdminCanEditField and continue from there.
Is there a better way to do this?
First, your backend should be as independent of the UI as possible. So, access control in UI is a good to have design, but you should not depend upon it.
Now, coming back to your question, yes you can use SecurityContextHolder to find out if the user if regular user/admin. However, if its possible, I would suggest making two controllers, one for admin and one for regular user. Use #PreAuthorize on the admin controller to restrict access. Having two separate controllers will increase readability of your code tremendously.
Additionally, you can call the same service class method from both the controllers. And since you already have two POJO classes, you can use them in #RequestBody and let Spring take care of the mappings for you.
Well, it depends what you think a better way would be. It also depends a bit on your data source. But as there is no information on that here, I would suggest that a better way to do yours is by inheritance.
Make UserPojo the super class and GeneralPojoAllFields extend that class.
UserPojo.java:
public class UserPojo {
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public UserPojo() {}
public UserPojo(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
GeneralPojoAllFields.java:
public class GeneralPojoAllFields extends UserPojo {
private String onlyAdminCanEditField;
public String getOnlyAdminCanEditField() {
return onlyAdminCanEditField;
}
public void setOnlyAdminCanEditField(String onlyAdminCanEditField) {
this.onlyAdminCanEditField = onlyAdminCanEditField;
}
public GeneralPojoAllFields() {}
public GeneralPojoAllFields(String firstName, String lastName, String onlyAdminCanEditField) {
super(firstName, lastName);
this.onlyAdminCanEditField = onlyAdminCanEditField;
}
}
App.java:
public class App {
public static void main(String[] args) {
UserPojo up1 = new UserPojo();
up1.setFirstName("MyFirstName");
up1.setLastName("MyLastName");
GeneralPojoAllFields gpaf1 = new GeneralPojoAllFields();
gpaf1.setFirstName("MyFirstName");
gpaf1.setLastName("MyLastName");
gpaf1.setOnlyAdminCanEditField("yes");
}
}

Java Builder pattern

I recently wrote a builder class and noticed that the standard seems to be as follows
public class PersonBuilder {
private String firstName;
private String lastName;
public PersonBuilder withFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public PersonBuilder withLastName(String lastName) {
this.lastName = lastName;
return this;
}
public Person build() {
return new Person(this);
}
}
Is there any disadvantage to, instead, doing the following
public class PersonBuilder {
private Person person;
public PersonBuilder withFirstName(String firstName) {
person.setFirstName(firstName);
return this;
}
public PersonBuilder withLastName(String lastName) {
person.setLastName(lastName);
return this;
}
public Person build() {
return person;
}
}
I understand this may be an opinion based question, I was just looking for any answers as to why this may be a bad or better design pattern.
There are several problems with your approach. Some of them are described in previous answers so I'll just mention the others.
The biggest problem with your design, is that you're using a single instance of Person in the builder. This means that if you're using the same builder more than once, you'll be "building" the same instance, while the clients using it are expecting two different instances. No need to mention that this could cause some serious havoc in your application.
The answer you got from #Basilevs mentions that the "built" class will require setters. This is absolutely true, but I'd just like to stress that this is a huge problem, since it means that the classes you "build" can never be immutable ! In other words, you're restricting the implementers of such classes to using synchronization for thread safety if needed, and other problem solving mechanisms that could have been avoided using the common approach.
Builder can be used when there is no setters in the class being built.
Accepting builder as constructor argument introduces tight coupling.
Following approach solves these:
public class PersonBuilder {
private String firstName;
private String lastName;
public PersonBuilder withFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public PersonBuilder withLastName(String lastName) {
this.lastName = lastName;
return this;
}
public Person build() {
return new Person(firstName, lastName);
}
}
Is there any disadvantage to, instead, doing the following
Yes, by the time the user call the withFirstName method it will result to NPE because you did not even instantiate person.

Should Java enum constants be retrieved through "get" methods or public final fields or both?

See below code for example:
public enum Employees {
BOB("Bob Barker", "BB", 100);
private String fullName; //are these better accessed through public or getFullName() below?
private String initials;
private String age;
Employees(String fullName, String initials, int age) {
this.fullName = fullName;
this.initials = initials;
this.age = age;
}
public String getFullName() {
return fullName;
}
//etc ...
}
Which method of accessing more correct or more memory efficient?
You cannot access the fullName through a static method. They are instance fields.
Your code is correct. You may wish to mark your String fields as final and rid yourself of the setXXX methods (since Enum values are traditionally immutable).
I would always make enum fields final, which then removes the utility of a setter. The enum instance is publicly shared and it is expected to be immutable by most sensible client code.
As far as the getter is concerned, that's up to your personal taste, although convention has it to add a getter and make the field private. So your taste has to be "strong".
use a getter its the convention ... and you won't get any nasty surprises if you at a later date use the enum within jstl/el which relies on the bean specification of using getters/is.
I think you are misunderstanding the concept of enums. An enum is a shared instance that does not change. What you describe is a regular mutable Java object. So the first thing you should do is switch from enum to class:
public class Employee {
private String fullName;
private String initials;
private String age;
public Employee(String fullName, String initials, int age) {
this.fullName = fullName;
this.initials = initials;
this.age = age;
}
public String getFullName() {
return fullName;
}
//etc ...
}
Then use your class like a regular class:
Employee bob = new Employee("Bob Barker", "BB", 100);
Edit
You have removed your setter now, but still, this still does not look like an enum to me.

Variable declarations conventions/rules in Java MVC pattern?

I am a novice in Java World. How to avoid confusion over variable declaration in MVC pattern over same variable?
For Example,
In Servlet (Controller):
String firstName = request.getParameter("firstname");
String lastName = request.getParameter("lastname");
In Bean (Model):
private String firstname;
private String lastname;
public Person(String FirstName, String LastName) {
setFirstName(FirstName);
setLastName(LastName);
}
//Getter and Setter Methods
public String getFirstName() {
return firstname;
}
public void setFirstName(String FirstName) {
this.firstname = FirstName;
}
public String getLastName() {
return lastname;
}
public void setLastName(String LastName) {
this.lastname = LastName;
}
In DAO (Data Access Layer):
public void savePerson(String firstName, String lastName) {
// Method statements
}
And in JSP (View):
${person.firstname} ${person.lastname}
My Questions/Confusion?
What is the proper way of declaring same variable in different
modules(controller,models,views,dao)? And how should I avoid confusion?
Is there any conventions I have to follow while declaring variables in different
modules?
Should variables in Servlets and DAO be same? Should variables in Models/Bean
be different from Servlet and DAO?
In your servlet these would be method variables. That's pretty fine.
In your Model this works as a Model's properties. That's pretty fine, too.
In view you are actually referring to Model's properties, and not declaring any variable, whatsoever.
In DAO, you are actually, persisting your Model.
So, In Servlet/Controller this will be something more like this,
Person p = new Person();
p.setFirstName(request.getParameter("firstname"));
p.setLastName(request.getParameter("lastname"));
And in your DAO, it would be more like this,
public void savePerson(Person person) {
// Method statements
}
Hence, declaration only happens in Model. I hope it clears your confusion.
I think the variable names you have used are fine. You can name your classes based on the type of the module. So you could name your classes using names like MyApplicationController, EmployeeModel, EmployeeDAO, etc.

Strategy for using Morphia to persist domain objects without adding unnecessary annotations to domain objects?

Hypothetically, lets say I have a domain object called Person. It looks like such:
public class Member {
private final String firstName;
private final String lastName;
private final String email;
private final String password;
public Member(String firstName, String lastName, String email, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
}
I also have a MemberRepository interface that defines basic CRUD and some other sugary methods.
Now lets say I want to persist this domain object in a MongoDB instance using Morphia. I've created my MorphiaMemberRepository implementation but what I'm unsure of is how to store the domain object with as little mess as possible.
Any Morphia users would know that I'd need to create an ID field of type ObjectId and annotate it with #Id. Additionally I'd need to annotate the class with #Entity("members"). I don't necessarily want to clutter up my nice domain object with the Morphia/MongoDB specific annotations.
So...fellow stackers, what should I do to keep this implementation as clean as possible?
That is the requirement for Morphia (at least the #Id one). Annotations do not require changing the way you use your object or serialization. They are just extra metadata which most programs ignore; they are harmless.
If you have a unique field then you don't need to add any new ones, just mark that with #Id and be done with it.
If you really don't want to do any of this, you can manually create the metadata in morphia to deal with your classes, but that will be much more work as that process is not exposed via any external configuration format.
Suppose there is IMember so Member implements IMember. Getter methods are defined in IMember.
Another class MorphiaMember implements IMember is annotated as necessary and has ID field (id is not always ObjectId).
Each class has a factory method
public static Member from(IMember mi) { ... }
so typical workflow will be:
MemberRepository repo = ...
Member m = Member.from(repo.get(some_id))
...
Member m2 = ...
repo.save(MorphiaMember.from(m))

Categories

Resources