Querying an Embedded element & Foreign Key Element within Android Room - java

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>
}

Related

JPA: How to map only one property from another entity

Let's say I have two entities:
#Entity
public class Phone {
#Id
private Long id;
private String number;
}
#Entity
public class Person {
#Id
private Long id;
private String name;
}
The relationship between a person and a phone is one to one.
How could I access only the phone's number in the Person entity mapped by the phone's id
#Entity
public class Person {
#Id
private Long id;
private String name;
// ???
private String phoneNumber;
}
The reason for not mapping the whole entity is because in some more realistic entities there are too many properties.
I don't think you can, but something like this might be acceptable:
public class Person {
#OneToOne
#JoinColumn(name = "phone_id")
private Phone phone;
public String getPhoneNumber() {
return phone.getNumber();
}
}
Although you have mapped the whole object, not just the single property, you have only exposed the single property you want. The other stuff is hidden.
Alternatively, do it at the DB layer using a View:
create view person_with_phone as
select p.id, p.name,f.number
from person p
join phone f on f.id=p.phone_id
and then have an entity class to match the view. You'll need to turn off schema creation in your JPA implementation.

hibernate mapping to a class with a list

I have 3 classes as shown below.
#Entity
public class Family (
#Id
private String familyName;
private int size;
#OneToMany
protected VehiclesList getVehiclesList()
// getters and setters
)
public class VehiclesList (
private List<Vehicle> vehicles;
#Transient
private int totalInsuranceCost
// getters and setters
}
#Entity
public class Vehicle (
#Id
private String plateNumber;
private String model;
private String color;
// getters and setters
)
I want to create two tables. First one is "Family" with columns as "size", etc. This is easy enough. Second, I want to create a "Vehicle" table with reference to Family. This table should have the following columns:
plateNumber
FamilyName
model
color
I would like the Family class to reference the VehiclesList class, so that I can access information from the VehiclesList class. None of the data in the VehiclesList class will be persisted to the database - only the vehicles. How can I do this?
VehicleList is not an entity so you cannot use OneToMany on it.
totalInsuranceCost should not be a property like this but more something for a service method like
VehicleService.calculateTotalInsuranceCostForFamily (String familyName).
Your family entity then becomes:
#Entity
public class Family (
#Id
private String familyName;
private int size;
#OneToMany(mappedBy = "family")
private List<Vehicle> vehicles;
// getters and setters
)

Foreign key usage in Java with Hibernate

I am trying to develop a web application and I was wondering if there is a way to utilize a foreign key without writing a lot of code.
My Trainees.java
#Entity
public class Trainees {
#Id
#GeneratedValue
private int traineesID;
private int groupsID;
#ManyToOne
#JoinColumn(name = "status_trainee")
private String status_TraineeID;
private int customersID;
private String name;
private String surname;
private String phoneDetails;
private String email;
public Trainees(){
}
public Trainees(String name, String surname, String phoneDetails, String email, int id, int groupsID, String status_TraineeID, int customersID) {
super();
this.name = name;
this.surname = surname;
this.email = email;
this.phoneDetails = phoneDetails;
this.groupsID = groupsID;
this.status_TraineeID = status_TraineeID;
this.customersID = customersID;
}
//getters and setters
#Override
public boolean equals(Object object) {
if (object instanceof Trainees){
Trainees contact = (Trainees) object;
return contact.traineesID == traineesID;
}
return false;
}
#Override
public int hashCode() {
return traineesID;
}
}
Status_Trainee.java
#Entity
public class Status_Trainee {
#Id
#GeneratedValue
private int status_traineeID;
private String value;
public Status_Trainee(){
}
public Status_Trainee(String value, int id) {
super();
this.value = value;
}
//getters and setters
#Override
public boolean equals(Object object) {
if (object instanceof Status_Trainee){
Status_Trainee value = (Status_Trainee) object;
return value.status_traineeID == status_traineeID;
}
return false;
}
#Override
public int hashCode() {
return status_traineeID;
}
}
Error: Caused by: org.hibernate.AnnotationException: #OneToOne or #ManyToOne on uaiContacts.model.Trainees.status_TraineeID references an unknown entity: String
So my aim is that using the Trainees table and class, I could retrieve the value of Status_Trainee table using the foreign key. For example: if foreign keys ID is 2, then it would retrieve a string from status_trainee table where primary key would match the foreign key ID.
I am using models, controlers, hibernate and angularjs to display to the view, I don't really want to pass the table through all this, I thought using something like ManyToOne or JoinColumns would retrieve the value?
Thanks for all the help!
You should add a reference to StatusTrainee in Trainee and annotate that with OneToMany, ManyToOne or OneToOne. Depending on which kind of relationship you will need a list of StatusTrainee or just a StatusTrainee.
Tip: dont use underscores in class names.
First of all, it is not recommended to use "_" in a class name when using hibernate. Hibernate uses underscores when accessing foreignKeys. So Lets Say you rename your class to: TraineeStatus and the id change it to traineeStatusId..
Secondly, You can use the Hibernate annotations for what you need. but first you need to know how the relation is:
#OneToMany : One Trainee can have lots of statuses
#ManytoOne : Many trainees can have the same status
#OneToOne : one Trainee Can only have one status and the other way around.
Try this:
#Entity
public class Trainees {
#Id
#GeneratedValue
private int traineesID;
private int groupsID;
#OneToOne
private TraineeStatus status;
private int customersID;
private String name;
private String surname;
private String phoneDetails;
private String email;
...
You can change the #OneToOne for the one you need..
Remember that hibernate will try to map this in your Trainees mysql table as status_traineeStatusId, so if you have this column (as an integer) at your trainess table you are done :)..
That is it..
Hope it helps

MySQL query / Hibernate Mapping not giving expected results

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!!

Hibernate criteria: search by content on a property list in an entity

I want to search by content on a property in an entity
I have a simple class to define a User:
#Entity
public class User {
#Id
#Column(name = "pers_id")
private int persId;
#Column(name = "full_name")
private String fullName;
#OneToMany
#JoinColumn(name = "PERS_ID")
private List<UserLanguages> languages = new ArrayList<UserLanguages>();
}
A User can have multiple languages, here is the class to make the link between user and a language.
#Entity
public class UserLanguages {
#Column(name="pers_id")
private int persId;
#Id
#Column(name="lang_iso_code")
private String langISO;
#Column(name="lang_full_name")
private String langFullName;
#Column(name="order_seq")
private int order;
}
#Entity
public class Language {
#Id
#Column(name="ID")
private long id;
#Column(name = "CODE")
private String code;
}
I have created a object to do search:
public class UserFilter {
private String name;
private List<Language> languages;
}
I have defined a service:
#Service("userService")
public class UserServiceImpl implements UserService {
#Override
public List<User> findByFilter(UserFilter userFilter) {
final Criteria criteria = userDao.createCriteria();
if (userFilter.getName() != null) {
for (final String token : userFilter.getName().toLowerCase().trim().split(" ")) {
criteria.add(Restrictions.like("fullName", "%" + token + "%"));
}
}
if (null != userFilter.getLanguages() && userFilter.getLanguages().size() > 0) {
final List<String> contents = new ArrayList<String>(userFilter.getLanguages().size());
for (final Language lang : userFilter.getLanguages()) {
contents.add(lang.getCode());
}
criteria.add(Restrictions.in("languages", contents));
}
return userDao.findByCriteria(criteria);
}
My question is how can I do search on languages. I want to find all users with this or thoses languages defined in the userFilter param.
The part about languages doesn't work in the method findByFilter in the service. Can you help me?
First of all, the UserLanguages entity should be named UserLanguage : it represents one language, and not several.
Then, the pers_id column is a foreign key to the User entity. It should thus be mapped as a ManyToOne relationship to the User entity rather than a basic column.
Finally, and to answer your question (I'll assume you want to find the users having at least one user language whose langISO code is in the contents list) : you should use a join :
// inner join between User and UserLanguages
criteria.createAlias("languages", "userLanguage");
// restriction on the langISO property of UserLanguage
criteria.add(Restrictions.in("userLanguage.langIso", contents));

Categories