Java Class Relationship and ORM - java

I have this simple login-registration functionality using the following classes.
User class:
public class User implements Serializable {
private int userId;
private String username;
private String password;
public User() {
userId = 0;
username = "";
password = "";
}
// public set-get methods here
}
Verification class:
public class Verification implements Serializable {
private int userId;
private String code;
private long expirationDate; // millis
public Verification() {
userId = 0;
code = "";
expirationDate = 0;
}
public void setUserId(int Id) {
userId = Id;
}
public void setUserId(User user) {
userId = user.getUserId();
}
// the rest of set-get methods here
}
I would like to confirm if the relationship above is considered Dependency? or Association?
Also, I'm using this classes in ORM. Does omitting one setUserId() overloaded method mess up the relationship between(if there's any)? Thank you.

I would say a dependency exists between Verification and User, as you can pass a User reference to a method of Verification (it uses that reference and depends on it), but Verification instance does not OWN a reference to a User instance, instead it consumes one.

The example you gave , describes dependency .
For reference you can visit the link given below -:
https://nirajrules.wordpress.com/2011/07/15/association-vs-dependency-vs-aggregation-vs-composition/

Related

Vaadin ThreadLocal for User Management

I'm currently developing a web application in Java which will be accessed by multiple users at the same time and as such need to store userdata in order to tailor the application to their individual requirements (such as what company they are apart of etc).
There are 2 classes that i use to manage this. User, MainSystem detailed below:
User
#Entity
public class User implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String username;
private String password;
private String type;
private String company;
private String DOB;
private String email;
private int PayrollId;
public User(String firstName, String lastName, String username, String password, String type, String company, String DOB, String email) {
this.firstName = firstName;
this. lastName = lastName;
this.username = username;
this.password = password;
this.type = type;
this.company = company;
this.DOB = DOB;
this.email = email;
}
MainSystem:
public class MainSystem {
public UserController userController;
private UserRepository userRepository;
private static ThreadLocal<User> loggedInUser = new ThreadLocal<>();
public DbController dbController;
public MainSystem(){
userController = new UserController(userRepository);
loggedInUser.set(new User());
}
public Boolean Login(String username, String password) {
if(userController.checkUser(username,password)){
User aUser = userController.getUser(username);
setLoggedInUser(userController.getUser(username));
VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
System.out.println("Logged in User: "+loggedInUser.get().getUsername());
return true;
}
else {
return false;
}
}
public static void setLoggedInUser(User user){
loggedInUser.set(user);
}
public static User getLoggedInUser() {
return loggedInUser.get();
}
Ideally what i'd like to do is access the ThreadLocal variable from another class, for instance the ViewProfile.View:
public class EditProfileView extends VerticalLayout implements View {
MainSystem main = new MainSystem();
NavigatorUI aUI = new NavigatorUI();
User aUser = main.getLoggedInUser();
TextField username = new TextField("Username");
TextField Id = new TextField("Id");
TextField email = new TextField("Email");
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField type = new TextField("Type");
PasswordField oldPassword = new PasswordField("Current Password");
PasswordField changePassword1 = new PasswordField("New Password");
PasswordField changePassword2 = new PasswordField("Confirm Password");
private UserController userController;
private UserRepository userRepository;
public EditProfileView() {
setDefaultComponentAlignment(Alignment.MIDDLE_CENTER);
userController = new UserController(userRepository);
setStyleName("backgroundImage");
setMargin(true);
setSizeFull();
addComponent(aUI.getHeader());
FormLayout content = new FormLayout(generateInfo());
Panel aPanel = new Panel("Edit User",content);
aPanel.setWidthUndefined();
content.setMargin(true);
aPanel.setStyleName(ValoTheme.PANEL_WELL);
addComponent(aPanel);
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
try {
aUser = main.getLoggedInUser();
System.out.println( aUser.getUsername());
Id.setValue(aUser.getId().toString());
username.setValue(aUser.getUsername());
firstName.setValue(aUser.getFirstName());
lastName.setValue(aUser.getLastName());
type.setValue(aUser.getType());
email.setValue(aUser.getEmail());
aUI.setUserMenu();
aUI.refreshPayroll();}
catch (Exception e){
System.out.println(e.getMessage());
}
}}
However, i'm finding that it is presenting me with a "null" value? I fear i may have missunderstood how ThreadLocal works. but essentially what i'm trying to achieve is to Store an instance relevant variable of the User.Class in MainSystem for other classes to use?
Any help would be appreciated.
My Solution:
My solution to this was to store the User.class in a VaadinSession Attribute like so:
public Boolean Login(String username, String password) {
if(userController.checkUser(username,password)){
User aUser = userController.getUser(username);
VaadinSession.getCurrent().setAttribute("user",aUser);
VaadinSession.getCurrent().setAttribute("username",loggedInUser.get().getUsername());
System.out.println("Logged in User: "+loggedInUser.get().getUsername());
return true;
}
else {
return false;
}
}
Then in other classes if i want to use that attribute i retrieved it like so:
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
try {
aUser = (User)VaadinSession.getCurrent().getAttribute("user");
}
catch (Exception e){
System.out.println(e.getMessage());
}
}
The problem is that there's no guarantee that MainSystem.Login() and EditProfileView.enter() will happen on the same thread. Every user action is processed as a separate HTTP request that the servlet container will run on any available thread.
For this kind of functionality, I would instead recommend storing the user information in the HTTP session. If you don't have any custom servlets or such, you could instead have a an field that contains the user object in your own custom UI class. Vaadin takes care of making UI.getCurrent() always return the right value in all code that is run through Vaadin.
If you instead also are integrating with other servlet functionality, you could store the user in the HttpSession instead. Generic servlet code can find the session through the getSession() method in e.g. servlet requests and response. In code run by Vaadin, you can use VaadinSession().getCurrent().getSession() to get a WrappedSession instance that is based on to the same HttpSession data.
There is also another approach. Instead it could be possible to make #SessionScoped user service, and either #Inject or #Autowire that depending whether you are using CDI or Spring. When doing this way, it will be the bean manager that takes care of binding correct entity with your view.

Jackson: having 2 different representations of a class

I have a simple User class:
public class User {
private long id;
private String username;
private String password;
private String someCommonData;
private String someAdminData;
}
I would like to have different representations of that User in json.
A version for normal users:
{"username":"myName", "someCommonData":"bla"}
and a representation for adminUsers:
{"id":1, "username":"myName", "someCommonData":"bla", "someAdminData":"don't show this to the user!"}
When I use #JsonIgnore then it is always ignored but I would like to have conditional ignore.
The only solution that would work so far is to have two different classes. Isn't there a more beautiful solution?
Take a look at #JsonView
public class User {
#JsonView({Admin.class})
private long id;
#JsonView({Basic.class})
private String username;
#JsonIgnore
private String password;
#JsonView({Basic.class})
private String someCommonData;
#JsonView({Admin.class})
private String someAdminData;
static class Basic {
}
static class Admin extends Basic {
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.id = 1L;
user.username = "admin";
user.password = "nimda";
user.someCommonData = "common-data";
user.someAdminData = "admin-data";
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
System.out.println(writer.withView(Basic.class).writeValueAsString(user));
System.out.println(writer.withView(Admin.class).writeValueAsString(user));
}
}
output of main:
{
"username" : "admin",
"someCommonData" : "common-data"
}
{
"id" : 1,
"username" : "admin",
"someCommonData" : "common-data",
"someAdminData" : "admin-data"
}
This blog explains the basics: http://www.baeldung.com/jackson-json-view-annotation
The best and easest aproach I can figure out is to use two classses. Sorry.
But it looks for me like a better design when you do this:
public class User {
private long id;
private String username;
private String password;
private String someCommonData;
}
public class Admin extends User {
private String someAdminData;
}

Passing objects as parameters in SugarORM

I have an object extending SugarRecord that looks like this:
public class SavedDraft extends SugarRecord {
private String name;
private String difficulty;
private int sport_id;
private LocalActivity localActivity;
public SavedDraft() {
}
public SavedDraft(String name, String difficulty, int ID, LocalActivity localActivity) {
this.name = name;
this.difficulty = difficulty;
this.sport_id = ID;
this.localActivity = localActivity;
}
}
The problem is that I always get a null object when I try to get the localActivity object from the database (see: SavedDraft.findById(SavedDraft.class, 1).getLocalActivity()), and I'm just wondering if it's possible to save objects as parameters in SugarORM at all.
This would be a relationship and you would need the LocalActivity to extend SugarRecord also.
See the documentation of Book and Author: http://satyan.github.io/sugar/creation.html

Models not being saved in Play Framework

Assume a model named User:
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
#Constraints.Required
public String password;
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
When I attempt to update an instance of User in my controller:
User user = User.find.where().eq("username", username).findUnique();
if(user != null) {
user.username = "some_new_username";
user.save();
}
no changes seem to be committed. I read somewhere that when you alter a model instance by its property, it does not get dirty and therefore no changes take place. Hence you should use a setter instead. In the documentation of Play Framework it is said that those setters (and getters) are generated automatically, but using user.setUsername(username) gives me a compilation error:
cannot find symbol [symbol: method setUsername(java.lang.String)] [location: class models.User]
Am I missing something?
Have you tried adding custom setters?
#Entity
public class User extends Model {
#Id
#Constraints.Min(10)
public Long id;
#Constraints.Required
public String username;
public void setUsername(String _username) {
username = _username;
}
#Constraints.Required
public String password;
public void setPassword(String _password) {
password = _password;
}
public static Finder<Long, User> find = new Finder<Long, User>(
Long.class, User.class
);
}
As far as I can tell, automatic getter/setter translation is broken in Play2. Your assignment:
user.username = "some_new_username";
should have triggered the function call:
user.setUsername("some_new_username");
This translation seems to be broken in Play 2. Here's my own question on the subject.

Relationships question in hibernate

I'm learning Hibernate and Play framework (also add Java into account...). I'm having problems saving this kind of entity
#Entity
#Table(name="users")
public class User extends Model {
#Required
public String username;
#Column(name="user_displayname",nullable=true)
public String displayname;
#Password
public String user_password;
#Email
#Column(name="user_email",nullable=false,unique=true)
public String user_email;
public String user_salt;
public Date user_joindate;
#ManyToOne
#JoinTable(name="users_meta")
public UserMeta userdata;
#Required
public boolean user_isActive;
#OneToOne(targetEntity=UserPhotos.class,cascade=CascadeType.ALL)
#JoinColumn(name="id",referencedColumnName="userID")
public UserPhotos userPhoto;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name="links_rol2user")
public List<Rol> rol;
public User (String username, models.Pass password, String user_email) {
this.username = username;
this.user_password = password.getHashedPassword();
this.user_salt = password.getUserHash();
this.user_email = user_email;
this.user_joindate = new Date();
this.user_isActive = false;
}
This is my code when I'm registering a user
// check if the validation has errors
if(validation.hasErrors()) {
params.flash(); // add http parameters to the flash scope
validation.keep(); // keep the errors for the next request
register();
} else {
Cache.delete(uuid);
Pass pass = new Pass(password,new Date().toString());
User newUser = new User(firstName, pass, email);
UserMeta utest = new UserMeta(newUser.id);
utest.setUserTownID(pueblos);
newUser.setUserMeta(utest);
newUser.save();
Logger.info("NewUser ID : %s", newUser.getId());
// UserMeta userInfo = new UserMeta(newUser.getId());
// userInfo.setUserTownID(pueblos);
// userInfo.save();
// TODO salvar foto a null
// Confirmation left
Cache.set("thankyou", "alright!", "3mn");
thankyou();
}
I'm trying to save the userMeta, it does creates a new record when I set the userMeta object into newUser (not visible right now), but it doesn't insert the new ID created in newUser.
What kind of relation do I need? before I tweaked the code as it is now, it was a OneToOne relationship, worked quite well, but now when I was completing the register functions it kinda hit me that I needed to save userMeta object too..
If you need more info let me know, I don't know if I explained it well or not, just trying to get the hang of how Hibernate do relations, etc.
Adding UserMeta:
*/
#Entity
#Table(name="users_meta")
public class UserMeta extends Model {
#Lob
#Column(name="userBio")
public String userBio;
#Column(name="userPhotoID",nullable=true)
public Long userPhotoID = null;
#Column(name="userRoleID", nullable=false)
public Long userRoleID = 2L;
#Lob
public String userDescription;
#Column(name="userViews", nullable=false)
public Long userViews = 0L;
#Column(name="userFavoriteCount", nullable=false)
public Long userFavoriteCount = 0L;
#Column(name="userTotalComments", nullable=false)
public Long userTotalComments = 0L;
#Column(name="userTotalUploadedVideos", nullable=false)
public Long userTotalUploadedVideos = 0L;
public Long userTownID;
public Long userID;
public UserMeta() {}
public UserMeta(Long userid) {
this.userBio = "El usuario no ha escrito nada todavia!";
this.userDescription = "El usuario todavia no se ha describido!";
this.userID = userid;
}
public Long getUserTownID() {
return userTownID;
}
public void setUserTownID(Long userTownID) {
this.userTownID = userTownID;
}
}
// pass model
public class Pass {
protected String hashed;
protected String userHash;
public Pass(String passwordToHash, String salt) {
StringBuffer passSalt = new StringBuffer(passwordToHash);
this.userHash = DigestUtils.md5Hex(salt);
passSalt.append(this.userHash);
passSalt.append(Play.configuration.getProperty("application.passwordSalt"));
this.hashed = DigestUtils.sha512Hex(passSalt.toString());
}
public String getHashedPassword() {
return this.hashed;
}
public String getUserHash() {
return this.userHash;
}
}
There seems to be a lot going on there! But from what I can tell, you problem is with the id that you are passing into the UserMeta.
As you are extending Model, the id is being generated by the Model class. However, this is not set until after the entity is saved to the database (as the id is auto-generated by the database).
Therefore, because you are passing the id into the UserMeta before the User object is saved, the value of id will be null.
If you can save the User object before you create your UserMeta object, your code should work.

Categories

Resources