I have a class with map inside. It is mapped with use of join table.
#Entity
#Table(name = "Sources")
#Lazy(false)
public class Sources {
#ManyToMany( fetch = FetchType.EAGER )
#JoinTable( name = "sources_lists", joinColumns = #JoinColumn( name = "list_id" ) )
#MapKeyColumn( name = "source_id" )
public Map<Integer, Source> getSources() { return sources; }
public void setSources( Map<Integer, Source> sourcesList ) { this.adSources = adSourcesList; }
private Map<Integer, Source> sources;
#Override
#Id #GeneratedValue(strategy = GenerationType.AUTO)
#Column( name="id", unique = true, nullable = false, updatable = false )
public Integer getId() { return super.getId(); }
}
I receive the following exception: "Unknown column 'sources0_.sources' in 'field list'".
When I change 'list_id' column name to the 'sources' things work, but I can't do this in production.
Tables are:
CREATE TABLE `sources` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`) );
CREATE TABLE `source` (
`DTYPE` varchar(31) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`className` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`));
CREATE TABLE `sources_lists` (
list_id` int(11) NOT NULL,
`source_id` int(11) NOT NULL,
KEY `FK54DCBD0B4307D0FC` (`source_id`),
KEY `FK54DCBD0B575FBECF` (`list_id`),
CONSTRAINT `FK54DCBD0B4307D0FC` FOREIGN KEY (`source_id`) REFERENCES `source` (`id`),
CONSTRAINT `FK54DCBD0B575FBECF` FOREIGN KEY (`list_id`) REFERENCES `sources` (`id`));
I realized that the issue was not with column, but with somethings else: I want to map Source objects by its id and Hibernate assumes that there are 3 columns in join table: parent object id (Sources class, list_id column), object id (Source class, source_id column) and a separate column for map key. I'll open other question to ask what is the way to map object in Hibernate by its id.
Related
I have one entity User. I need ManyToMany bidirectional relation User-User pairs in one field. How I can do it?
#Entity
#Table(name = "users")
public class User {
#Id
private int id;
private Set<User> pairs;
}
I tried like this:
#ManyToMany
#JoinTable(name = "pairs", joinColumns = {
#JoinColumn(name = "a"),
#JoinColumn(name = "b")
})
private Set<User> pairs;
And got next result: org.hibernate.AnnotationException: A Foreign key refering com.calm.model.entity.User from com.calm.model.entity.User has the wrong number of column. should be 1
Db scmema generated by ddl:
CREATE TABLE `users` (
`id` int(11) NOT NULL,
...
PRIMARY KEY (`id`)
)
And expected pairs table:
CREATE TABLE `pairs` (
`a` int(11) NOT NULL, //user 1
`b` int(11) NOT NULL, //user 2
PRIMARY KEY (`a`,`b`)
)
And expected behavior like:
SELECT b as id2 FROM pairs WHERE a = :id1
UNION
SELECT a as id2 FROM pairs WHERE b = :id1
I have two tables :
CREATE TABLE IF NOT EXISTS `DB`.`global_history` (
`ID` INT(11) AUTO_INCREMENT,
`ID_HISTORY` INT(11) NULL,
PRIMARY KEY (`ID`),
CONSTRAINT `FK_HISTORY_GLOBAL_HISTORY`
FOREIGN KEY (`ID_HISTORY`)
REFERENCES `DB`.`history` (`ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
Second table :
CREATE TABLE IF NOT EXISTS `DB`.`history` (
`ID` INT(11) AUTO_INCREMENT,
`TIMESTAMP` DATETIME NOT NULL,
PRIMARY KEY (`ID`));
but when I try to delete a row in History (Second table) I get this error :
--> Cannot delete or update a parent row : a foreign key constraint fails
And I want the relationship to be #ManyToOne So when I remove a row from global_history it will not remove any row from history
And this is my model class :
Global history :
#ManyToOne
#JoinColumn(name = "ID_HISTORY", nullable = true)
private History history;
--> history is a simple class
when you define a F.K from a child (global_history) to parent (History table), child table can not has invalid F.K. so you should decide for deleting parent which cause F.K will be invalid.
a foreign key with cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. This is called a cascade delete in SQL Server.
so if you want to prevent deleting corresponding child rows , you can set null value or default value by using following command:
ON DELETE SET NULL
ON DELETE SET DEFAULT
this is complete format:
CREATE TABLE child_table
(
column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],
...
CONSTRAINT fk_name
FOREIGN KEY (child_col1, child_col2, ... child_col_n)
REFERENCES parent_table (parent_col1, parent_col2, ... parent_col_n)
ON DELETE CASCADE
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
)
https://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php
I have a table of Orders, and a table of Order Status Updates that points to order.id. I need to get a list of Orders, but I need to join in order status updates because I don't want orders which last status is 'Cancelled'
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`end_customer_id` bigint(20) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `FK_end_customer` (`end_customer_id`),
CONSTRAINT `orders_ibfk_3` FOREIGN KEY (`end_customer_id`) REFERENCES `end_customers` (`id`) ON UPDATE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=100333 DEFAULT CHARSET=utf8;
CREATE TABLE `order_status_updates` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`status` varchar(255) NOT NULL,
`date` datetime NOT NULL,
`order_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_order` (`order_id`),
CONSTRAINT `order_status_updates_ibfk_3` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=344180 DEFAULT CHARSET=utf8;
Current Criteria is:
final Criteria c = criteria("o")
.add(eq("o.endCustomer.id", endCustomerId));
return list(c.addOrder(desc("createdAt")));
I need to filter out Orders which latest status (sorted by Date) is Cancelled
Assuming a class called MyOrder and an ORDER_STATUS enum as well as id, status and createdAt field definitions:
final Criteria c = sessionFactory.getCurrentSession().createCriteria(MyOrder.class);
c.add(Restrictions.eq("id", yourId))
.add(Restrictions.ne("status", ORDER_STATUS.CANCELLED)
.addOrder(Order.desc("createdAt"));
I have model orders and it gives me an error when I am trying to apply it:
Database 'default' is in an inconsistent state! An evolution has not
been applied properly. Please check the problem and resolve it
manually before marking it as resolved.
While trying to run SQL script below, we got the following error:
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax to use
near 'order ( id bigint auto_increment not null, description '
at line 1 [ERROR:1064, SQLSTATE:42000], while trying to run this SQL script:
The script:
package models;
import play.data.format.Formats;
import play.db.ebean.Model;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
#Entity
public class Order extends Model{
#Id
#Version
#GeneratedValue(strategy=GenerationType.IDENTITY)
public Long id;
#Column(columnDefinition="TEXT")
public String description;
public Boolean status;
#Formats.DateTime(pattern="dd/MM/yyyy")
public Date dueDate = new Date();
#Formats.DateTime(pattern="dd/MM/yyyy")
public Date dueDate2 = new Date();
public Double total;
public Order(){
//this.name=name;
//.description=description;
}
public static Finder<Long, Order> find=new Finder<Long, Order>(Long.class, Order.class);
public static List<Order> findAll() {
return find.all();
}
public static void create(String name,String description){
Order newMenu=new Order();
newMenu.save();
}
public static void update(Long id,String name,String description){
Order restaurant= Order.find.ref(id);
System.out.println("id:"+id);
//restaurant.name=name;
/*restaurant.description=description;
restaurant.update();*/
}
public static void delete(Long id){
find.ref(id).delete();
}
}
SQl:
# --- Rev:1,Ups - 50058ce
create table category (
id bigint auto_increment not null,
name varchar(255),
description TEXT,
menu_id bigint,
parent_category bigint,
constraint pk_category primary key (id))
;
create table menu (
id bigint auto_increment not null,
name varchar(255),
description TEXT,
constraint pk_menu primary key (id))
;
create table menu_item (
id bigint auto_increment not null,
title varchar(255),
short_title varchar(255),
description TEXT,
price_original integer,
price_for_sale integer,
image varchar(255),
status tinyint(1) default 0,
cook_time integer,
prep_instruction TEXT,
category_id bigint,
unit ENUM('кг','л','штук'),
constraint ck_menu_item_unit check (unit in ('gramm','litr','item')),
constraint pk_menu_item primary key (id))
;
create table order (
id bigint auto_increment not null,
description TEXT,
status tinyint(1) default 0,
due_date datetime,
due_date2 datetime,
total double,
constraint pk_order primary key (id))
;
create table order_type (
id integer auto_increment not null,
title varchar(255),
description TEXT,
status varchar(255),
constraint pk_order_type primary key (id))
;
create table restaurant (
id bigint auto_increment not null,
name varchar(255),
description TEXT,
image varchar(255),
contact varchar(255),
address TEXT,
constraint pk_restaurant primary key (id))
;
create table restaurant_section (
id bigint auto_increment not null,
name varchar(255),
description TEXT,
image varchar(255),
constraint pk_restaurant_section primary key (id))
;
create table smeny (
id bigint auto_increment not null,
name varchar(255),
opened TEXT,
closed TEXT,
constraint pk_smeny primary key (id))
;
create table user_test (
email varchar(40) not null,
password varchar(255),
name varchar(255),
role integer,
constraint pk_user_test primary key (email))
;
alter table category add constraint fk_category_menu_1 foreign key (menu_id) references menu (id) on delete restrict on update restrict;
create index ix_category_menu_1 on category (menu_id);
alter table category add constraint fk_category_parent_category_2 foreign key (parent_category) references category (id) on delete restrict on update restrict;
create index ix_category_parent_category_2 on category (parent_category);
alter table menu_item add constraint fk_menu_item_category_3 foreign key (category_id) references category (id) on delete restrict on update restrict;
create index ix_menu_item_category_3 on menu_item (category_id);
order is a reserved word in MySQL check. So you better change the name of your table.
I'm testing JPA, in a simple case File/FileVersions tables (Master/Details), with OneToMany relation, I have this problem: in FileVersions table, the field "file_id" (responsable for the relation with File table) accepts every values, not only values from File table.
How can I use the JPA mapping to limit the input in FileVersion.file_id only for values existing in File.id?
My class are File and FileVersion:
FILE CLASS
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="FILE_ID")
private Long id;
#Column(name="NAME", nullable = false, length = 30)
private String name;
//RELATIONS -------------------------------------------
#OneToMany(mappedBy="file", fetch=FetchType.EAGER)
private Collection <FileVersion> fileVersionsList;
//-----------------------------------------------------
FILEVERSION CLASS
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="VERSION_ID")
private Long id;
#Column(name="FILENAME", nullable = false, length = 255)
private String fileName;
#Column(name="NOTES", nullable = false, length = 200)
private String notes;
//RELATIONS -------------------------------------------
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="FILE_ID", referencedColumnName="FILE_ID", nullable=false)
private File file;
//-----------------------------------------------------
and this is the FILEVERSION TABLE
CREATE TABLE `JPA-Support`.`FILEVERSION` (
`VERSION_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`FILENAME` varchar(255) NOT NULL,
`NOTES` varchar(200) NOT NULL,
`FILE_ID` bigint(20) NOT NULL,
PRIMARY KEY (`VERSION_ID`),
KEY `FK_FILEVERSION_FILE_ID` (`FILE_ID`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
Thanks for help,
I know the SQL constraint to limit the input, but it is possible to create this SQL costraint using some annotation, without writing by hand the SQL in the database?
I'm new on JPA, I was thinking that using #JoinColumn annotation, JPA could create also the costraint...
Thank you again.
At the Java level, you describe and annotate associations between classes - which and you did - and your mapping looks fine.
At the database level, if you want to restrict the possible values in the file_id column to values that are primary keys in the FILE table, you should use a foreign key constraint. To do so, you will need to use InnoDB tables. Something like that:
CREATE TABLE `JPA-Support`.`FILEVERSION` (
`VERSION_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`FILENAME` varchar(255) NOT NULL,
`NOTES` varchar(200) NOT NULL,
`FILE_ID` bigint(20) NOT NULL,
PRIMARY KEY (`VERSION_ID`),
FOREIGN KEY `FK_FILEVERSION_FILE_ID` (`FILE_ID`) REFERENCES FILE(ID)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
The table FILE also has to use InnoDB. Actually, use InnoDB tables for the tables for which you want to use referential integrity.