In my database, each user has a department and a userlevel. These are denoted in the users table with their department_id and their userlevel_id. The corresponding User java classes also has a department and userlevel field.
I need to select all the users from my db with a given username and password, and automatically map their department and userlevel object to their User object.
I have my Users, Departments and Userlevels class (automatically generated by hibernate pojo mapping) as follows:
public class Users implements java.io.Serializable {
private Integer id;
private Departments departments;
private Userlevels userlevels;
private String username;
private String password;
private String salt;
private String email;
private String firstName;
private String lastName;
public Users() {
}
//Getters and setters
}
public class Departments implements java.io.Serializable {
private Integer id;
private String name;
public Departments() {
}
//Getters and Setters
}
}
public class Userlevels implements java.io.Serializable {
private Integer id;
private String name;
public Userlevels() {
}
//Getters and Setters
}
}
I have an SQL query as such:
SQLQuery q = session.createSQLQuery("SELECT u.*,d.*,ul.* FROM users u, departments d, userlevels ul WHERE u.department_id=d.id AND u.userlevel_id=ul.id AND u.username=? AND u.password=?");
q.setString(0, "usernameToGet");
q.setString(1, "passwordToGet");
q.addEntity("u", Users.class);
q.addJoin("dept", "u.departments");
q.addJoin("ulevels", u.userlevels");
List<Users> users = q.list();
Right now I'm getting the correct User object with its corresponding department object, but the userlevels object is returning null....
Any help would be appreciated, Thanks!!
Related
I need to create a composite GSI based on 3 different fields and query the data. I cannot find any resource which can point me to the correct direction and usage of this. Would appreciate some help on how this can be achieved ?
The table is as below:
#Data
#NoArgsConstructor
#DynamoDBTable(tableName = TABLE_NAME)
public class MyTable {
#DynamoDBHashKey(attributeName = NAME)
private String name;
private Person person;
}
Person.java
public class Person {
private String name;
private String age;
private Gender gender; //Gender is an enum : MALE, FEMALE, OTHER
private String occupation;
.
.
.
and so on
}
Do I need to create another object like PersonV2 and then create an index on it or it should be done in a different way ?
APPROACH :
public class PersonV2 {
private String name;
private String age;
private Gender gender;
}
and the my table will look like this ?
#Data
#NoArgsConstructor
#DynamoDBTable(tableName = TABLE_NAME)
public class MyTable {
#DynamoDBHashKey(attributeName = NAME)
private String name;
private Person person;
#DynamoDBIndexHashKey(attributeName = MY_INDEX_ATTRIBUTE_NAME, globalSecondaryIndexName = MY_INDEX_NAME)
private PersonV2 personV2;
}
Is this the correct way to handle this ?
I have a Hibernate model with id, name and surname. I am using it to get data from the database and then at the GET end-point is this one:
#GetMapping(value = "/contacts", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Contact> allContacts() {
return contactService.findAll();
}
As you can see it returns the Contact object. Actually it is a Hibernate entity.
The problem is that when I use this code
#PostMapping("/contacts")
public Contact createContact(Contact contact) {
return contactService.createContact(contact);
}
it asks not only name and surname but also the id. POST methods should not ask for id since they are not created yet. What should I do so that it doesn't ask for an id?
Edit: Here is the Contact.java class
import lombok.Data;
import javax.persistence.*;
#Entity
#Data
public class Contact {
public Contact() {
}
public Contact(Integer id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(columnDefinition = "serial")
private Integer id;
private String name;
private String surname;
}
Define a ContactInput class that only has the attributes you want the user to input and then create some mapping code that creates a valid Contact based on the ContactInput.
You should create ContactDto class
#Data
public ContactDto class {
private String name;
private String surname;
}
In #PostMapping you are gonna get ContactDto from the user. You cannot saved ContactDto into your database. So you need to map ContactDto to Contact. What you can do is simply create ContractMapper class.
public static contactDtoToEntity(ContactDto dto){
Contact dbContact = new Contact();
dbContact.setName(dto.getName());
dbContact.setSurname(dto.getSurname());
return dbContact;
}
Before you saved the contact in your database in service layer, you need to map it and then save. Id is gonna be generated in the database.
I'm new to how the Room Database works particularly Querying and was wondering how one would go about querying the following.
Querying an object that contains an embedded object within it, based
on the embedded object.
Querying an object that contains a foreign key
#Entity
#Entity
public class Car {
#PrimaryKey()
private String id;
#Embedded()
private Engine engine
#Ignore
private List<Tire> tires
... //relevant getters and setters
}
public class Engine {
private String id;
private String type;
private String name;
}
#Entity(foreignKeys = {#ForeignKey(
entity = Car.class, parentColumn = "id", childColumn ="carIdFk")
}
public class Tire {
#PrimaryKey(autogenerated=true)
private int id;
private String model;
private String rimModel;
private String cardIdFk;
}
#Dao
public interface CarDao {
//Need a query to retrieve all cars where engine id == <somevalue>
//Need a query to retrieve all cars where tire model == <somevalue>
}
#Dao
public interface TyreDao {
//Need a query to retrieve all cars where tire id == <somevalue>
}
Here is my User class:
#NodeEntity
public class User {
#GraphId
private Long id;
#Property
private String name;
#Property
private String email;
#Property
private String password;
#Property
private String photoLink;
#Property
private Integer age;
#Property
private Country country;
#Property
private Gender gender;
#Property
private String about;
#Property
private boolean online;
private Collection<UserHasLanguage> hasLanguage;
#Relationship(type="HAS_ROLE", direction=Relationship.OUTGOING)
private Collection<Role> roles;
#Relationship(type="HAS_IN_FRIENDLIST", direction=Relationship.OUTGOING)
private Collection<User> friendList;
#Relationship(type="HAS_IN_BLACKLIST", direction=Relationship.OUTGOING)
private Collection<User> blackList;
So I want users to have one-side relationships HAS_IN_FRIENDLIST to other users.
At the service level I have a method for adding friends to user:
public void addToFriendList (User whoAdds, User whoIsAdded)
throws UserNotFoundException{
if (whoIsAdded == null)
throw new UserNotFoundException("User not found");
Collection<User> friendList = whoAdds.getFriendList();
if (friendList == null)
friendList = new HashSet<>();
friendList.add(whoIsAdded);
whoAdds.setFriendList(friendList);
userRepository.save(whoAdds);
}
However, when I use this method, some previous relationships "HAS_IN_FRIENDLIST" of this user are removed.
I have noticed, that whoAdds.getFriendList() method always returns only 1 User.
How can I fix this?
I can't test this, but my understanding is that Collection isn't supported. For a list, you must use one of these (as specified here)
java.util.Vector
java.util.List, backed by a java.util.ArrayList
java.util.SortedSet, backed by a java.util.TreeSet
java.util.Set, backed by a java.util.HashSet
Arrays
So change Collection<User> to Set<User>
I'm currently developing a system using PLAY framework and JPA. My problem is that I can't save an EMPLOYEE if Department_id (which is connected to another Entity class) is Null or has no value.
Here is my Employees Entity Class
#Entity
public class Employees{
#Id
public int employee_id;
public String first_name;
public String last_name;
public String email;
public String phone_number;
public java.sql.Date hire_date;
public String salary;
public String commission_pct;
#ManyToOne
#JoinColumn(name="department_id",nullable = true)
private Departments department_id;
#ManyToOne
#JoinColumn(name="job_id")
private Jobs job_id;
#ManyToOne
#JoinColumn(name="manager_id",nullable = true)
private Employees manager_id;
#OneToMany(mappedBy = "manager_id")
Set<Employees> emps = new HashSet<Employees>();
}
Here is my Departments Entity Class.
#Entity
public class Departments {
#Id
private String department_id;
private String department_name;
private int manager_id;
#OneToMany(mappedBy="department_id")
private Set<Employees> emps = new HashSet<Employees>();
}
Here is the error
Caused by: org.hibernate.TransientObjectException: object references an unsaved
transient instance - save the transient instance before flushing: modelsDomain.E
mployees.department_id -> modelsDomain.Departments
at org.hibernate.engine.CascadingAction$9.noCascade(CascadingAction.java
:387) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]
at org.hibernate.engine.Cascade.cascade(Cascade.java:172) ~[hibernate-co
re-3.6.9.Final.jar:3.6.9.Final]
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(
AbstractFlushingEventListener.java:154) ~[hibernate-core-3.6.9.Final.jar:3.6.9.F
inal]
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFl
ushes(AbstractFlushingEventListener.java:145) ~[hibernate-core-3.6.9.Final.jar:3
.6.9.Final]
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverything
ToExecutions(AbstractFlushingEventListener.java:88) ~[hibernate-core-3.6.9.Final
.jar:3.6.9.Final]
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlus
hEventListener.java:50) ~[hibernate-core-3.6.9.Final.jar:3.6.9.Final]