hibernate mapping to a class with a list - java

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
)

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.

Querying an Embedded element & Foreign Key Element within Android Room

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

How to create correct entities mapping?

I would like to use ORM Hibernate. And faced with issue below.
There are few tables that have translation on different languages. e.g. it looks like this:
In the database I can use join and get all required data
e.g.:SELECT * FROM car c
JOIN translation t on c.description = t.description
WHERE t.type = 'CAR'
As you can see table 'translation' has column 'type' that uses for filtering by type.
So the main question how to create correct entities and mapping?
A car has OneToMany translations. Similary a city has OneToMany translation.
But every translation has zero to one car or zero to one city.
A translation is either for a Car or a City because its description talks about either City or Car. This is achieved by ManyToOne notation. There is no annotation in hibernate to explicitly say the range from Zero. Following is just to get an Fair Idea of mappings. I am not assuming any relation between City and Car even though I can think city has OneToMany cars.
#Entity
class Car
{
private int Id;
private String name;
//.......... declare all variables that you need
#OneToMany(mappedBy = "car")
private List<Translation>
//getters and setters
}
#Entity
class City
{
private int Id;
private String name;
//.......... declare all variables that you need
#OneToMany(mappedBy = "city")
private List<Translation>
//getters and setters
}
#Entity
class Translation
{
private int Id;
private String language;
//.......... declare all variables that you need
#ManyToOne
private Car;
#ManyToOne
private City;
//getters and setters
}

Aggregation relationship via JPA annotations

I am trying to establish the aggregation relationship between two Java classes through JPA annotations in order to persist them into a database.
public class Ticket
{
private String ticketNo;
private Date releasedDate;
private boolean printed;
}
public class Discount
{
private String percentage;
private Date releasedDate;
private boolean printed;
}
Such as mentioned here, the aggregation relationship is unidirectional and thus, only it is necessary to map one side. From the solution given by this page, I think the solution will be:
public class Discount
{
private String percentage;
private Date releasedDate;
private boolean printed;
#ManyToOne(name="TICKET_ID")
private Ticket ticket;
}
However, in some examples of aggregation, the many side class appears inside the one side class. Thus, I am considering this too:
public class Ticket
{
private String ticketNo;
private Date releasedDate;
private boolean printed;
#OneToMany(mappedBy="ticket")
private List<Discount> discounts = new ArrayList<Discount>();
}
Which option is the proper one?
This how you map a unidirectional many-to-one relationship:
#Entity
public class Ticket {
#Id
#GeneratedValue
private Long id;
private String ticketNo;
private Date releasedDate;
private boolean printed;
// getters and setters
}
#Entity
public class Discount {
#Id
#GeneratedValue
private Long id;
private String percentage;
private Date releasedDate;
private boolean printed;
#ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "TICKET_ID") // you can rename the join column
private Ticket ticket;
// getters and setters
}
Note:
JoinColumn (foreign key in the database terminology) must be on the many side of the relationship (this is the Discount in your case).
The #Id annotations are also mandatory. In this case, the ID will be generated by the persistence provider automatically. If you are using database sequence or table or some other strategy you can redefine it.
That looks right to me. A discount has a ticket. You could also include the discounts accessible from the tickets like ticket.getDiscounts() if you need to access them in a query such as SELECT t FROM Ticket t WHERE t.discounts.percentage >= :discountPercentage.
#Entity
public class Ticket {
#Id
private String ticketNo;
private Date releasedDate;
private boolean printed;
#OneToMany(mappedBy = "ticket", fetch = FetchType.LAZY)
private List<Discounts> discounts;
}
#Entity
public class Discount {
private String percentage;
private Date releasedDate;
private boolean printed;
#ManytoOne(name="TICKET_ID")
private Ticket ticket;
}
However, I wouldn't recommend using #OneToMany as this can create problems serializing too much data to JSON if you are returning this as JSON results or just lazily loading too much data by accident. You should always be able to work with just #ManyToOne as an example if you did not put the #OneToMany association query can be SELECT t FROM Discount d INNER JOIN d.ticket t WHERE d.percentage >= :discountPercentage

Indexing composite object in spring mongodb

I have a composite object that I wish to store in mongodb (using spring annotations). The object is as follows:
#Document(collection="person")
class Person {
#Id
private String id;
private Address address;
private String name;
}
and the composite class Address:
#Document
class Address {
#Indexed
private Long countryId;
private String street;
#Indexed
private String city
}
I need both country and city to be indexed as part of the person collection. Alas, no index is created for them. Any ideas how to create the index?
I have tried the following which works but is not elegant:
#Document(collection="person")
#CompoundIndexes({
#CompoundIndex(name = "countryId", def = "{'address.countryId': 1}")
})
class Person {
You can set up multiple secondary indexes, if you wish. This would be a good place to start.

Categories