I have table performance and hours. One performnace can be played many times at certain hours. One to Many relations.
#Entity
#Table(name = "performance_type")
#Data
public class PerformanceType {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer performanceTypeId;
#Column(length=127)
private String performOptions;
}
and
#Entity
#Table(name = "performance")
#Data
public class Performance {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer performanceId;
#OneToMany(mappedBy = "performance")
private List<Hours> performanceHours = new ArrayList<>();
}
In database hibernate create table hours that have performanceId thas have only one value. How i may insert list values that performance with id 1,4,7 are played in the same time. That i need additoinal table hours_performance that store hourId and perfomanceId?
Since the relationship you want to achieve is (according to my understanding) many-to-many, you do indeed need a third table mapping hours to relationships. Here is a very good example. You will need to set up your third table with two foreign keys to the two tables you want to connect.
#Entity
#Table(name = "performance")
#Data
public class Performance {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer performanceId;
#ManyToMany
#JoinTable(
name = "hours_performance",
joinColumns = { #JoinColumn(name = "performance_id") },
inverseJoinColumns = { #JoinColumn(name = "hour_id") }
)
private List<Hours> performanceHours = new ArrayList<>();
}
#Entity
#Table(name = "hours")
#Data
public class Hours {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(nullable = false, unique = true)
private Integer hourId;
ZonedDateTime time;
#ManyToMany(mappedBy = "performanceHours")
private List<Performance> performances;
}
Related
I have 3 tables as #Entity, and 2 join tables in my spring + hibernate app.
In one of join table i have extra column. I want to take info from this info column when i take info from my main table.
Main table code:
#Entity
#Table(name = "items")
public class Items {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "name")
private String name;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "crafts"
,joinColumns = #JoinColumn(name = "item_id")
,inverseJoinColumns = #JoinColumn(name = "plot_id"))
private Set<Plots> plotInfo = new HashSet<>();
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "item_materials"
,joinColumns = #JoinColumn(name = "item_id")
,inverseJoinColumns = #JoinColumn(name = "material_id"))
private Set<Materials> materialsInfo = new HashSet<>();
Table item_materials have this columns "id, item_id(fkey), material_id(fkey), expense" and one of this which names as "expense" i need to have in my final result.
How can i code my class to have "expense" in my result?
I read about #embeddable but still dont understand how to use in my project.
Don't use a #ManyToMany association. Map the join table as entity and model it similar to this:
#Entity
#Table(name = "items")
public class Items {
#OneToMany(mappedBy = "item")
private Set<Crafts> plotInfo = new HashSet<>();
}
#Entity
#Table(name = "plots")
public class Plots {
#OneToMany(mappedBy = "plot")
private Set<Crafts> items = new HashSet<>();
}
#Entity
#Table(name = "crafts")
public class Crafts {
#EmbeddedId
private CraftsId id;
#ManyToOne
#JoinColumn(name = "item_id", insertable = false, updatable = false)
private Items item;
#ManyToOne
#JoinColumn(name = "plot_id", insertable = false, updatable = false)
private Plots plot;
}
#Embeddable
public class CraftsId {
#Column(name = "item_id")
private Integer itemId;
#Column(name = "plot_id")
private Integer plotId;
// equals + hashCode
}
I have these 3 entities:
Payment Transactions:
#Entity
#Table(name = "payment_transactions")
public class PaymentTransactions implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
.....
}
WPF Payments:
#Entity
#Table(name = "wpf_payments")
public class WpfPayments implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
............
}
WPF Payments Payment transactions:
#Entity
#Table(name = "wpf_payment_payment_transactions")
public class WpfPaymentPaymentTransactions implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false, length = 3)
private int id;
#Column(length = 4)
private Integer wpf_payment_id;
#Column(length = 4)
private Integer payment_transaction_id;
.....
}
I use these SQL requests to get proper data based in id:
SELECT `payment_transactions`.* FROM `payment_transactions` INNER JOIN `wpf_payment_payment_transactions` ON `payment_transactions`.`id` = `wpf_payment_payment_transactions`.`payment_transaction_id` WHERE `wpf_payment_payment_transactions`.`wpf_payment_id` = 75 ORDER BY `payment_transactions`.`id` ASC LIMIT 1
SELECT `payment_transactions`.* FROM `payment_transactions` INNER JOIN `wpf_payment_payment_transactions` ON `payment_transactions`.`id` = `wpf_payment_payment_transactions`.`payment_transaction_id` WHERE `wpf_payment_payment_transactions`.`wpf_payment_id` = 75
Is there some way to implement these SQL requests using JPA queries?
If you are using JPA 2.0, it is not possible to use JPQL with your queries since you cannot use the ON clause.
One solution is to implement a Bidirectional Mapping on the entities WpfPaymentPaymentTransactions,
PaymentTransactions to be able to make a join :
#Entity
#Table(name = "payment_transactions")
public class PaymentTransactions implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
#OneToOne(mappedBy="paymentTransactions") //or OneToMany depending on your model
private WpfPaymentPaymentTransactions wpfPaymentPaymentTransactions;
}
#Entity
#Table(name = "wpf_payment_payment_transactions")
public class WpfPaymentPaymentTransactions implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false, length = 3)
private int id;
#ManyToOne
#JoinColumn(name="wpf_payment_id")
private PaymentTransactions paymentTransactions;
}
Then you can join the two entities like this :
SELECT t FROM PaymentTransactions t
INNER JOIN WpfPaymentPaymentTransactions wppt
Starting from JPA 2.1, You can add the ON clause with JPQL query. So for the first query, it will be like this :
SELECT t FROM PaymentTransactions t
INNER JOIN WpfPaymentPaymentTransactions wppt
ON t.id = wppt.paymentTransactionId`
WHERE wppt.wpfPaymentId = :param
ORDER BY t.id ASC LIMIT 1
Hope it helps!
everyone! Sorry but I need some help. My db is looking this way, I try to do same throught the Hibernate in Java.
But I don`t understand how I need to annoted this relations with so many different tables.
It`s a part of my Abiturient table.
#Entity
#Table (name = "abiturient",
uniqueConstraints = {#UniqueConstraint(columnNames = {"id"})})
public class Abiturient {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, unique = true, length = 11)
#ManyToOne
private Long id;
#Column
private Date data_narodjennya;
#Column
private Integer city_village;
It`s a part of my nomer_telefonu table
#Entity
#Table(name = "nomer_telefonu")
public class NomerTelefonu {
#Id
#Column(name = "nomer_tel_id", nullable = false, unique = true, length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long nomer_tel_id;
#Column(name = "nomer")
private String nomer;
#Column(name = "id")
#OneToMany(fetch = FetchType.LAZY)
private Set<Abiturient> id;
I don`t think that all there is right, `cos every time I try to solve problem I get an error and need other type.
Use #OneToMany bidirectional relation.
#Entity
public class Abiturient {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "abiturent")
private List<NomerTelefonu> phones = Lists.newArrayList();
}
#Entity
public class NomerTelefonu{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "nomer_tel_id")
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
private Abiturient abiturent;
}
Lists.newArrayList() from guava. This is working mapping. Always use the simplest version to experiment.
what is #JoinColumn and how it is used in Hibernate
You can use this project to play with mappings in the unit tests:
https://github.com/v-ladynev/hibernate-experimental
How can I include a referenced table column in a unique constraint? I want to create a unique constraint for table Survey for columns toEmail, receipt.receiptSeries and receipt.receiptNum.
See entities below please:
Receipt
#Entity
#Table(name = "RECEIPT")
public class Receipt {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "RECEIPT_SERIES")
private String receiptSeries;
#Column(name = "RECEIPT_NUM")
private String receiptNum;
}
Survey
#Entity
#Table(name = "SURVEY"}
public class Survey {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#ManyToOne(optional = false)
#JoinColumn(name = "RECEIPT_ID")
private Receipt receipt;
#Column(name = "TO_EMAIL")
private String toEmail;
}
I've tried using the approach below with no success:
#Table(name = "SURVEY", uniqueConstraints = {
#UniqueConstraint(columnNames = {"TO_EMAIL", "RECEIPT.RECEIPT_SERIES", "RECEIPT.RECEIPT_NUM"})})
Using a composite primary key with receiptSeries and receiptNum for Receipt is not an option.
Try something like this
#Table(name="notification_status", uniqueConstraints=
arrayOf(UniqueConstraint(columnNames= arrayOf("external_user_id",
"external_organization_id",
"notification_id"))))
I use hibernate and spring-data. There are two tables with many-to-many relationship.
#Entity
#Table(name = "FirstEntity")
public class FirstEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_entity_id")
private Long id;
#Column(name = "first_entiry_name")
private String name;
/* getters and setters are below*/
}
#Entity
#Table(name = "SecondEntity")
public class SecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "second_entity_id")
private Long id;
#Column(name = "second_entiry_name")
private String name;
#Column(name = "second_entiry_desc")
private String description;
/* getters and setters are below*/
}
And entity for cross-reference table.
#Entity
#Table(name = "FirstSecondEntity")
public class FirstSecondEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "first_second_entity_id")
private Long id;
#Column(name = "first_entity_id")
private Long firstEntityId;
#Column(name = "second_entity_id")
private Long secondEntityId;
/* getters and setters are below*/
}
I need SELECT like this
SELECT FirstEntity.name, SecondEntity.name, SecondEntity.description FROM SecondEntity INNER JOIN FirstSecondEntity ON SecondEntity.id = FirstSecondEntity.secondEntityId INNER JOIN User ON FirstEntity.id = FirstSecondEntity.firstEntityId
i.e. I need all records from cross-reference table where instead of ids there is actual info from entities.
Inserting this query into #Query annotation in my CrudRepository-extended class doesn't work because of
ERROR [main][org.hibernate.hql.internal.ast.ErrorCounter] Path expected for join!
So I need your help.
Your join table is all screwed up. In this case, you actually don't even need the join table as a hibernate mapping:
In Second Entity add the following list:
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "FirstSecondEntity",
joinColumns = {
#JoinColumn(name = "first_entity_id",
nullable = false,
updatable = false) },
inverseJoinColumns = {
#JoinColumn(name = "second_entity_id",
nullable = false,
updatable = false) },
)
private List<FirstEntity> firstEntities;
In FirstEntity add the following list:
#ManyToMany(fetch = FetchType.LAZY,
mappedBy = "firstEntities")
private List<SecondEntity> secondEntities;