I created a simple spring mvc web app with hibernate and mysql (Everything worked well). Then, I changed mysql to oracle. After first run of the application, (connected to oracle database) tables, corresponding to the entity models defined in my application, were created. I added one country and one user to COUNTRY and MYAPPUSER tables from SQL DEVELOPER. Now, I am trying to get a user from MYAPPUSER table but I am getting null instead of user, which exists.
This is User entity:
#Entity
#Table(name = "myAppUser")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "id_Sequence")
#SequenceGenerator(name = "id_Sequence", sequenceName = "ID_SEQ")
#Column(name = "Id", updatable = false, nullable = false)
private int id;
#Column(name = "FirstName")
private String firstName;
#Column(name = "LastName")
private String lastName;
#Column(name = "Username")
private String username;
#Column(name = "Password")
private String password;
#OneToMany(mappedBy = "user")
private List<UserSubject> userSubjects;
#ManyToOne
#JoinColumn(name = "country_id", nullable = false)
private Country country;
#OneToMany(mappedBy = "user")
private List<Test> testList;
//and getters and setters
}
This is code while debugging:
In sql developer:
this is generated sql by hibernate:
I am interested in why user is null after selecting data and why question marks are in place of user1 and 123 in generated sql?
I think this effect is specific to oracle, because I had not such problem with MySQL database.
P.S Exceptions aren't thrown....
From the comments the solution was to commit in SQL Developer.
Related
I have 3 tables which are Person Login and Account.
Person and Login is OneToOne relation and Login has one FK which is connected Person's id column called PERSON_ID.
Person(one) and Account(many) is OneToMany relation and Account has one FK which is connected Person's id column called PERSON_ID as well .
what i want to do is when i delete one data from Account , nothing happen to Person and Login.
if i delete one data from Person which id=1, Login's PERSON_ID=1 data will be deleted , and all of the data PERSON_ID=1 from Account will be deleted as well.
if i delete one data from Login which PERSON_ID=1, Person 's id=1 data will be deleted , and all of the data PERSON_ID=1 from Account will be deleted as well.
how should i set the cascade ?
i've tried dozens of times and still can't find the logic in there, thanks!!
here's my code of all 3 tables without setting cascade:
`
#Entity
#Table(name = "PERSON")
public class Person {
#Id
#Column(name = "ID", nullable = false, unique = true)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "NAME")
private String name;
#Column(name = "SEX")
private String sex;
#OneToMany(mappedBy = "person",fetch = FetchType.LAZY)
private List<Account> account;
#OneToOne(mappedBy = "person")
private Login login;
#get..
#set..
}
`
#Entity
#Table(name = "ACCOUNT")
public class Account {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "ACCOUNT")
private String account;
#Column(name = "AMOUNT")
private String amount;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "PERSON_ID",referencedColumnName = "ID")
public Person person;
#get..
#set..
}
`
#Entity
#Table(name = "LOGIN")
public class Login {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
private long id;
#Column(name = "USERNAME")
private String userName;
#Column(name = "PASSWORD")
private String password;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "PERSON_ID", referencedColumnName = "ID")
private Person person;
#get..
#set..
}
It's been a while, but if I'm not mistaken you need to use the cascade=REMOVE option on the OneToMany and OneToOne relationships. In the OneToOne I think you need to specify cascade=REMOVE on the side that does NOT own the relationship, that is, the side that also contains the "mappedBy" property.
Finally, I believe JPA will NOT automatically load lazy relationships and then cascade them. I'm thinking you may need to fetch the relationship before you delete the parent entity (otherwise JPA will not know what to delete).
I am creating web application in Spring andI was using local MySql database and everything was good.
But I decided to use online free database.
when i am trying to execute any JpaRepository query, I got error like this:
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 '?3_4_0_, employee0_.permission as permissi4_4_0_,
employee0_.ulica as ulica5' at line 1
#Entity
#Data
#Builder
#Table(name = "`Pracownicy`")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "`id`")
private int id;
#Column(name = "`Imię`")
private String name;
#Column(name = "`Nazwisko`")
private String surname;
#Column(name = "`Ulica`")
private String street;
#Column(name = "`Miasto`")
private String town;
#Column(name = "`Kod_pocztowy`")
private String zipCode;
#Column(name = "`Permission`")
private String permission;
#Column(name = "`id_aktywnego_zamówienia`")
private Integer activeOrder;
#OneToOne(cascade = {CascadeType.ALL}, mappedBy = "employee")
private EmployeeLogin employeeLogin;
#OneToMany(cascade = {CascadeType.ALL}, mappedBy = "employee")
#LazyCollection(LazyCollectionOption.FALSE)
private List<Order> orders = new ArrayList<>();
}
Any ideas why?
These are my propertise.
spring.datasource.url=jdbc:mysql://sql2.freesqldatabase.com:3306/sql2270378?allowPublicKeyRetrieval=true&useSSL=false
spring.datasource.username= *********
spring.datasource.password= **********
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
I have User and Role classes with ManyToMany relationship. When I'm adding Role object to List roles in User object the 'user_roles' table columns 'username' and 'role_name' gets populated with User and Role objects primary keys' which are their ids. I wanted to know whether its possible to reference not primary keys(ids) and get username and Role.name in those columns instead?
#Entity
#Table(name = "users")
#SecondaryTable(name = "user_info", pkJoinColumns = {
#PrimaryKeyJoinColumn(name = "info_id", referencedColumnName = "user_id") })
public class User {
#Id
#Column(name = "user_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#ManyToMany
#JoinTable(name="user_roles",
joinColumns= {#JoinColumn(name="username"/*, referencedColumnName="username"*/)},
inverseJoinColumns= {#JoinColumn( name="role_name"/*, referencedColumnName="role_name"*/)}
)
private List<Role> roles;
#Entity
#Table(name = "roles")
public class Role {
#Id
#Column(name = "role_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "role_name")
private String name;
#ManyToMany
private List<User> users;
Also if I remove the comments around referencedColumnName I get error when trying to fetch all users from the database. I haven't added any data to database so even when querying empty database I'm getting this error:
Caused by: org.hibernate.HibernateException: Found shared references
to a collection: com.recipee.model.User.roles
The reason I'm using such database schema is because I'm trying to use Tomcat realm authentication where I need username and role_name in one database table.
I am trying to implement order management system by hibernate, which I am not very familiar with. The exception asked me to manually execute sql the same as hibernate in my program tried, and it succeeded. I don't know what's the problem. Probably it's from design issues. Database is like this:
ORDER has a foreign key ITEM_ID pointing to ITEM_ID in ITEM table, it's a one to many relationship and another foreign key CLIENT_ID pointing to CLIENT_ID in CLINET table.
Three entities' definition with annotation are written as
#Table(name = "ITEM")
public class Item implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "ITEM_ID", unique = true, nullable = false)
private int item_id;
#Column(name = "NAME")
private String name;
#Column(name="CATEGORY")
private String category;
#Column(name="UNIT")
private String unit;
#Column(name="PRICE")
private double price;
//getters and setters
}
#Entity
#Table(name="CLIENT")
public class Client implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "CLIENT_ID", unique = true, nullable = false)
private int client_id;
#Column(name="CLIENT_NAME")
private String client_name;
//getters and setters
}
#Entity
#Table(name="ORDER")
public class Order {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "ORDER_ID", unique = true, nullable = false)
private int order_id;
#ManyToOne(cascade = CascadeType.PERSIST,targetEntity=Client.class)
#JoinColumn(name = "CLIENT_ID", nullable = false)
private Client client;
#ManyToOne(cascade = CascadeType.PERSIST,targetEntity=Item.class)
#JoinColumn(name = "ITEM_ID", nullable = false)
private Item item;
#Column(name="QUANTITY")
private double quantity;
#Temporal(TemporalType.DATE)
#Column(name = "ORDER_DATE")
private Date order_date;
//getters and setters
}
The order data insertion function is like:
public static void insertNewOrder(Item item,Client client, double quantity, Date date){
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Order order = new Order();
order.setItem(item);
order.setClient(client);
order.setQuantity(new Double(quantity));
order.setOrder_date(date);
session.save(order);
session.getTransaction().commit();
session.close();
}
Here is my exception:
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 (CLIENT_ID, ITEM_ID, ORDER_DATE, QUANTITY) values (1, 1, '2013-11-12', 1.4' at line 1
Exception in thread "main" org.hibernate.exception.SQLGrammarException: 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 (CLIENT_ID, ITEM_ID, ORDER_DATE, QUANTITY) values (1, 1, '2013-11-12', 1.4' at line 1
I have tried that sql manually, and it did insert successfully. I can't find any clue where the problem could be. Please help.
ORDER is a MySQL keyword. If you must use it as a table name you need to wrap every reference in backticks.
SELECT * FROM `ORDER`...
I recommend you chnage the table name to something that doesn't conflict
I have the following entity (getters and setters ommited)...
#Entity
#Table(name = "TBL_PROJECT_RUN")
public class ProjectRunEntity {
#Id
#Column(name = "ID")
#GeneratedValue(generator = "StakeholdersSequence")
#SequenceGenerator(name = "StakeholdersSequence", sequenceName = "STAKEHOLDERS_UPDATE_SEQ", allocationSize = 1)
private Integer id;
#Column(name = "REPORT_RUN_DATE")
private Date systemRunDate;
#Column(name = "JIRA_PROJECT_NAME")
private String jiraProjectName;
#Column(name = "JIRA_PROJECT_DESC")
private String jiraProjectDescription;
#Column(name = "RUNBY")
private String runBy;
#Column(name = "HEADER_TEXT")
private String headerText;
#Column(name = "FOOTER_TEXT")
private String footerText;
#Column(name = "JIRA_ID")
private String jiraId;
#Column(name = "TO_EMAIL")
private String toEmail;
#Column(name = "CC_EMAIL")
private String ccEmail;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "projectRunEntity")
private List<ProjectRunDetailsEntity> projectRunDetailsEntities;
Then I commit it to the database like this...
final Session session = sessionProvider.get();
session.persist(projectRunEntity);
session.flush();
return projectRunEntity.getId();
The id returned here is not what the actual id in the database is, it is 1 or 2 off. Please note I am sharing one sequence for all ids in all tables in my project so that any given entity has a project-wide unique index. What would cause the id to be incorrect like this?
It turns out that the web ui for oracle express automatically created triggers than insert an id from this sequence before inserting my row object. This meant that the generator in oracle was always 1 behind. To solve this I removed the triggers.
Two possibilities spring to mind:
You say you have a shared sequence. Are you inserting into other tables at the same time? (which could increment the sequence).
Is there a trigger on the database table which inserts a sequence value into the id column?