Hibernate marker interface mapping using jpa - java

Hi I am new to hibernate and am facing problem in mapping marker interface.
I have a marker interface.
public interface Item{}
Then there are two classes which implement this interface:
public class Hotel implements Item{
private int id;
private String name;
private String location;
.......
}
public class Restaurant implements Item{
private int id;
private String name;
private String cuisine;
.......
}
There is another class which uses these two classes:
public class ItineraryItem {
private int id;
private Item item;
}
How can I map these classes using annotations.

Code:
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Item {
#Id
private int id;
}
#Entity
public class Hotel extends Item {
#Column
private String name;
#Column
private String location;
}
#Entity
public class Restaurant extends Item {
#Column
private String name;
#Column
private String cuisine;
}
#Entity
public class ItineraryItem {
#Id
private int id;
#JoinColumn
private Item item;
}
InheritanceType.TABLE_PER_CLASS will cause Hotel and Restaurant to have their own separate tables.
You can find more information here: http://en.wikibooks.org/wiki/Java_Persistence/Inheritance

Related

I used crudrepository findAll() method on MAGICNOTIFY_CARD_INFO table but it shows other columns from another table MAGICNOTIFY_PRICE

I tried to select all columns from the table MAGICNOTIFY_CARD_INFO, so i wrote a code;
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MagicnotifyApplication.class, args);
MagicnotifyCardInfoRepository magicnotifyCardInfoRepository =
context.getBean(MagicnotifyCardInfoRepository.class);
magicnotifyCardInfoRepository.findAll();
//SpringApplication.run(MagicnotifyApplication.class, args);
}
and this is the entity i wanted to select;
public class MagicnotifyCardInfoID implements Serializable {
#Column(name = "koname")
private String koname;
#Column(name = "name")
private String name;
#Column(name = "cardkingdom")
private String cardkingdom;
#Column(name = "cardkingdomfoil")
private String cardkingdomfoil;
#Column(name = "set")
private String set;
#Column(name = "setName")
private String setName;
#Column(name = "reldate")
private Date reldate;
#Column(name = "rarity")
private String rarity;
#Column(name = "uuid")
private String uuid;
#ManyToOne
private MagicnotifyUuidName magicnotifyUuidName;
#ManyToOne
private MagicnotifySetInfo magicnotifySetInfo;
}
public class MagicnotifyCardInfo implements Serializable {
#EmbeddedId
private MagicnotifyPriceID id;
}
public interface MagicnotifyCardInfoRepository extends JpaRepository<MagicnotifyCardInfo, Long> {
#Query(value = "SELECT * FROM MAGICNOTIFY_CARD_INFO", nativeQuery = true)
List<MagicnotifyCardInfo> findByAll();
List<MagicnotifyCardInfo> findAll();
}
but after querying, it tries to select other column item from table
MAGICNOTIFY_PRICE;
public class MagicnotifyPriceID implements Serializable {
#Column(name = "foil")
private BigDecimal foil;
#Column(name = "normal")
private BigDecimal normal;
#Column(name = "date")
private Date date;
#Column(name = "key")
private String key;
#ManyToOne
private MagicnotifyUuidName id;
}
public class MagicnotifyPrice implements Serializable {
#EmbeddedId
private MagicnotifyPriceID id;
}
I'm not sure why it happens from differently mapped two tables; how can i select from initial table MAGICNOTIFY_CARD_INFO and select from its columns?
First of all, you have not mentioned any primary key using #Id annotation inside either of your MagicnotifyCardInfoID class or MagicnotifyPriceID class
Secondly, you have given same #EmbeddedId fields "MagicnotifyPriceID id" in both the below classes
public class MagicnotifyCardInfo implements Serializable {
#EmbeddedId
private MagicnotifyPriceID id;
}
public class MagicnotifyPrice implements Serializable {
#EmbeddedId
private MagicnotifyPriceID id;
}
I don't see #Embeddable used anywhere in your program
Please refer https://www.baeldung.com/jpa-embedded-embeddable
public interface MagicnotifyCardInfoRepository extends JpaRepository<MagicnotifyCardInfo, Long> {
#Query(value = "SELECT * FROM MAGICNOTIFY_CARD_INFO", nativeQuery = true)
List<MagicnotifyCardInfo> findByAll();
List<MagicnotifyCardInfo> findAll();
}
In the above class you are passing "JpaRepository<MagicnotifyCardInfo, Long>"
Long as the data type of a primary key in your entity "MagicnotifyCardInfo"
which does not even exist.
Please fix these and try again.

getting error during the creation of relationship between JPA entities

I'm trying to create entities but I got the following error.
Internal Exception: Exception [EclipseLink-7157] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity class [class application.Team] must use a #JoinColumn instead of #Column to map its relationship attribute [mPlayers].
These are my entities, I need to store data into the database using the Java Persistence API (JPA). To do so I create entities as following. Maybe I have created the relationships between entities in the wrong way.
Person
#MappedSuperclass
public class Person {
#Id
#GeneratedValue( strategy= GenerationType.AUTO )
protected int p_id;
protected String firstName;
protected String middleName;
protected String lastName;
protected String phone;
protected String email;
public Person() {
}
}
Player
#Entity
#Table( name = "tbl_players")
#AttributeOverride(name="id", column=#Column(name="player_id"))
public class Player extends Person implements Serializable{
private int player_id;
#Column(name = "goals_in_year")
private int numberOfGoalsInCurrentYear;
private boolean goalie;
#Column(name = "defended_goals")
private int defendedGoals;
public Player(){
}
}
Manager
#Entity
#Table( name = "tbl_manager")
#AttributeOverride(name="id", column=#Column(name="manager_id"))
public class Manager extends Person implements Serializable{
private String dob;
private int starRating;
#OneToOne
private Team teamToManage;
public Manager(){
}
}
Team
#Entity
#Table( name = "tbl_team")
public class Team implements Serializable {
#Column(name = "team_name")
#Id
String teamName;
#OneToOne
Manager manager;
#Column(name = "team_players")
#OneToMany
private List<Player> mPlayers = new ArrayList<>();
#Column(name = "jersey_color")
String jerseyColor;
public Team(){
}
}
League
#Entity
public class League {
#Id
private int league_id;
#OneToMany
#Column(name = "League Teams")
private List<Team> mTeam = new ArrayList<>();
public void addTeam(Team team) {
mTeam.add(team);
}
public void removeTeam(Team team) {
mTeam.remove(team);
}
}
Use #JoinColumn for Mapping (#OneToMany, #ManyToMany, #ManyToOne) instead of #Column. #Column is used to specify the mapped column for a persistent property or field.
Player
#Entity
#Table( name = "tbl_players")
#AttributeOverride(name="id", column=#Column(name="player_id"))
public class Player extends Person implements Serializable{
private int player_id;
#Column(name = "goals_in_year")
private int numberOfGoalsInCurrentYear;
private boolean goalie;
#Column(name = "defended_goals")
private int defendedGoals;
#OneToOne // or #OneToMany as you desire
#JoinColumn(name="team_name") // here the name you have given to the column in tbl_players
private Team team;
public Player(){
}
}
Manager
#Entity
#Table( name = "tbl_manager")
#AttributeOverride(name="id", column=#Column(name="manager_id"))
public class Manager extends Person implements Serializable{
private String dob;
private int starRating;
#OneToOne(mappedBy="manager")
private Team teamToManage;
public Manager(){
}
}
Team
#Entity
#Table( name = "tbl_team")
public class Team implements Serializable {
#Id
#Column(name = "team_id")
private int id;
#Column(name = "team_name")
String teamName;
#OneToOne
#JoinColumn(name="manager_id")
Manager manager;
#Column(name = "team_players")
#OneToMany(mappedBy="team")
private List<Player> mPlayers = new ArrayList<>();
#Column(name = "jersey_color")
String jerseyColor;
#ManyToOne(mappedBy="")
private League league;
public Team(){
}
}
League
#Entity
#Table( name = "tbl_league")
public class League {
#Id
#Column(name="league_id")
private int league_id;
#OneToMany
#JoinTable(name="tbl_league_teams",joinColumns=#JoinColumn(name = "league_id"), inverseJoinColumns=#JoinColumn(name = "team_id"))
private List<Team> mTeam = new ArrayList<>();
public void addTeam(Team team) {
mTeam.add(team);
}
public void removeTeam(Team team) {
mTeam.remove(team);
}
}
Create new intermiditate mapping table named tbl_league_teams with columns league_id and team_id to facilitate the #JoinTable in League entity to map between teams in a league.
It seems to be due to #Column(name = "team_players") and #OneToManyPlease
Please read the link
https://stackoverflow.com/a/24206471/11207493
Why dont u treat each model class as an entity then u join the model using either ManyToOne or OneToMany

Using CrudRepository interface to auto-implement methods that return different type of objects

I am trying to convert a Spring MVC application into a combo of Spring REST + Angular2 app.This is my 'Ticket.java' entity class (skipped getters and setters)
#Entity
#Table(name="ticket")
public class Ticket {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#ManyToOne
#JoinColumn(name="bookings_id")
private Booking booking;
#ManyToOne
#JoinColumn(name="customer_id")
private Customer customer;
#Column(name="seat_no")
private int seatNumber;
public Ticket(){
}
How do I write a method in TicketDAO that returns all the customers given the booking.id? Here is the TicketDAO.java interface
public interface TicketDAO extends CrudRepository<Ticket, Integer>{
// I want to auto-implement such type of method using CrudRepository
// public List<Customer> getCustomersBooking(int bId); }
I have previously implemented such method as :
#Override
public List<Customer> getCustomersBooking(int bId) {
Session currentSession = sessionFactory.getCurrentSession();
logger.info("DAOgetCustomersBooking: D1");
List<Customer> customer = new ArrayList<Customer>();
Query<Ticket> theQuery =
currentSession.createQuery("from Ticket where bookings_id = "+bId, Ticket.class);
List<Ticket> tickets = theQuery.getResultList();
for (Ticket temp: tickets){
customer.add(temp.getCustomer());
}
return customer;
}
But now I want to auto-implement such type of method using CrudRepository in the TicketDAO interface. How will I write a method declaration that will enable me to do so?
For Reference, Booking.java
#Entity
#Table(name="bookings")
public class Booking {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#ManyToOne
#JoinColumn(name="van_id")
private Van van;
#ManyToOne
#JoinColumn(name="driver_id")
private Driver driver;
#ManyToOne
#JoinColumn(name="route_id")
private Route route;
#Column(name="registered_seats")
private int registeredSeats;
#Column(name="departure_time")
private String departureTime;
#Column(name="arival_time")
private String arrivalTime;
#Column(name="departure_date")
private String departureDate;
#Column(name="expected_price")
private int expectedPrice;
//Ticket.java reference
#OneToMany(mappedBy="booking",fetch=FetchType.LAZY,cascade=CascadeType.ALL)
private Set<Ticket> tickets;
//Webdata.java reference
#OneToOne(mappedBy="bookingWebdata",fetch=FetchType.LAZY,cascade=CascadeType.ALL)
private Webdata webdata;
Customers.java
#Entity
#Table(name="customer")
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="email")
private String email;
#Column(name="username")
private String username;
#Column(name="password")
private String password;
#Column(name="regnumber")
private int regNumber;
#Column(name="phonenumber")
private int phoneNumber;
#Column(name="flagged")
private int flagged;
//Ticket.java reference
#OneToMany(mappedBy="customer",cascade=CascadeType.ALL)
private Set<Ticket> tickets;
for a project I used JpaRepository but I think that's the same kind of request.
You have to use #Query() with HQL based on your java entities.
I gave object directly in the request and not the id so I don't know if you can do with id as I do with object.
Like this :
public interface TicketDAO extends CrudRepository<Ticket, Integer>{
#Query("SELECT t.customer FROM Ticket t WHERE t.booking = ?1")
public List<Customer> getCustomersBooking(Booking booking);
}
If you want to try with id, it would be around that :
public interface TicketDAO extends CrudRepository<Ticket, Integer>{
#Query("SELECT t.customer FROM Ticket t WHERE t.booking.id = ?1")
public List<Customer> getCustomersBooking(int bId);
}

What is the best way to save a task entity by associating it with the user it belongs to?

Task Class
#Entity
public class Task {
#Id
#GeneratedValue
private Integer id;
private String title;
private String text;
private boolean done;
}
User class, which contains the tasks
#Entity
public class TodolistUser {
#Id
#GeneratedValue
private Integer id;
private String login;
private String password;
#Autowired
#ElementCollection
private List<Task> tasks;
}
and service
#Service
public class TodolistUserService {
#Autowired
private TodolistUserRepository repository;
}
How could I persist a task relating it to the user it belongs to, using the repository that extends from JpaRepository?
You have to change certain things :
Task Class
#Embedabble // or #Entity if you want to use #OneToMany in TodoListUser
public class Task {
#Id
#GeneratedValue
private Integer id;
private String title;
private String text;
private boolean done;
}
User class, which contains the tasks
#Entity
public class TodolistUser {
#Id
#GeneratedValue
private Integer id;
private String login;
private String password;
#Autowired // Not Recommended
#ElementCollection
private List<Task> tasks = new ArrayList<Task>(); // Or other implementations
}
#Service
public class TodolistUserService {
#Autowired
private TodolistUserRepository repository;
public void addFoo(TodoListUser foo){
repository.save(foo);
}
}

JPA subclass with #IdClass and no attributes

I have a subclass Entity with no #Id or #Column attribute.
but my subclass entity has #IdClass as follows
#Entity
#Table(name = "Employee")
#IdClass(EmployeeEntityPK.class)
public class EmployeeEntity extends AbstractEntity {
#Override
public void setName(String name) {
super.setName(name);
}
#Override
public void setLocation(String location) {
super.setLocation(location);
}
#Override
public void setEmpId(Integer empId) {
super.setEmpId(empId);
}
}
When I try to deploy my project. I am getting exception from hibernate
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547) [rt.jar:1.6.0_17]
at java.util.ArrayList.get(ArrayList.java:322) [rt.jar:1.6.0_17]
at org.hibernate.cfg.AnnotationBinder.getUniqueIdPropertyFromBaseClass(AnnotationBinder.java:2576)
at org.hibernate.cfg.AnnotationBinder.isIdClassPkOfTheAssociatedEntity(AnnotationBinder.java:925)
at org.hibernate.cfg.AnnotationBinder.mapAsIdClass(AnnotationBinder.java:824)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:671)
complete exception is in http://pastebin.com/SnhQ1ZVQ
Hibernate is trying to find #Id class from my Entity which is not there.
How can I resolve this issue.
My super class is as follows
#MappedSuperclass
public class AbstractEntity implements Serializable {
#Id
#Column(name = "empId")
private Integer empId;
#Column(name = "Name")
private String name;
#Column(name = "LOCATION")
private String location;
public Integer getEmpId() {
return empId;
}
//along with other getter setters
}
If I have a primary key with more than one column I use the normal #Id Property on the class I want to use as Pk. The Id-Class is annotated with #Embeddable...
example:
Entity:
#Entity
public class Foo extends AbstractEntity implements Serializable {
private static final long serialVersionUID = 1;
#EmbeddedId
private FooPK id;
//Getter, Setter...
}
EmbeddedId:
#Embeddable
public class FooPK implements Serializable {
private static final long serialVersionUID = 1;
private Integer firstId;
private Integer SecondId;
public FavoritenPK() {
}
// Setter, Getter...
}
EDIT:
I had troubles having the #Id in MappedSuperclass. Try not to put the #Id-Property in Mapped-Superclass!

Categories

Resources