I am getting the following error from my Hibernate code:
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Unknown column 'bulletin0_.bulletin_date' in 'field list'
There is no such bulletin_date column in my table, nor is there such a name in my model class. It's just called date. Here is the line where I'm getting the error.
Query query = session.createQuery("from Bulletin where approved = true");
Here is my model class (I'm leaving out the getters and setters):
public class Bulletin {
#Id
#Column(name="id")
#GeneratedValue
private int id;
#Column(name="date")
private String date;
#Column(name="name")
private String name;
#Column(name="subject")
private String subject;
#Column(name="note")
private String note;
#Column(name="approved")
private boolean approved;
}
Here is my table definition.
+----------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date | varchar(10) | YES | | NULL | |
| name | varchar(30) | YES | | NULL | |
| subject | varchar(50) | YES | | NULL | |
| note | varchar(2500) | YES | | NULL | |
| approved | tinyint(1) | YES | | NULL | |
+----------+---------------+------+-----+---------+----------------+
I had the wrong column names in my Bulletin.hbm.xml file. When I corrected it, the problem was solved.
Related
Having this two classes:
Address.java:
#Embeddable
#Data
#AllArgsConstructor
#NoArgsConstructor
#Builder
public class Address {
private String street;
private String city;
private String state;
private String pincode;
}
User.java:
#Entity
#Data
public class User {
#Id
private int id;
private String name;
#ElementCollection
private Set<Address> addresses = new HashSet<>();
}
DemoApplication.java:
#Bean
CommandLineRunner dataLoader2(UserRepository userRepo){
return new CommandLineRunner() {
#Override
public void run(String... args) throws Exception {
User u = new User();
u.setName("Some random name");
Address a1 = Address.builder()
.street("First Street")
.city("first city")
.state("first state")
.pincode("100001")
.build();
Address a2 = Address.builder()
.street("Second Street")
.city("Second city")
.state("second state")
.pincode("200002")
.build();
u.setAddresses(new HashSet<>(Arrays.asList(a1, a2)));
userRepo.save(u);
}
};
}
When run, if fails with this error:
GenerationTarget encountered exception accepting command : Error
executing DDL "alter table user_addresses drop foreign key
FKfm6x520mag23hvgr1oshaut8b" via JDBC Statement
Yet, the final tables are created:
describe user_addresses:
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| user_id | int | NO | MUL | NULL | |
| city | varchar(255) | YES | | NULL | |
| pincode | varchar(255) | YES | | NULL | |
| state | varchar(255) | YES | | NULL | |
| street | varchar(255) | YES | | NULL | |
+---------+--------------+------+-----+---------+-------+
describe user:
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
Why cannot the jdbc drop the foreign key user_id in table user_addresses? How to make the jdbc to do so?
"USER" is a reserved word in MySQL and that might be the root cause of the issue. Change the name of the User entity or add #Table annotation to it and define a different name.
Reference documentation:
https://dev.mysql.com/doc/refman/5.7/en/keywords.html
https://dev.mysql.com/doc/refman/8.0/en/keywords.html
I've got a MySQL database schema with 3 tables as follows:
mysql> describe results;
+--------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| run_at | datetime | YES | | NULL | |
| trials | int(10) unsigned | YES | | NULL | |
+--------------+------------------+------+-----+---------+----------------+
mysql> describe result_details;
+------------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| results_id | int(10) | NO | | NULL | |
| summarys_id | int(10) | YES | | NULL | |
+------------------------+------------------+------+-----+---------+----------------+
mysql> describe summarys;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| mean | double | YES | | NULL | |
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+-------+------------------+------+-----+---------+----------------+
Where a Result object can have several ResultDetail members. However, semantically, it makes sense to have one of these details stand out among the rest as a 'overall' detail. Therefore, I have the following classes:
Result.java (some members and methods removed for brevity)
#Entity
#Table(name="results")
public class Result extends BaseEntity {
#Column(name="run_at")
#Temporal(TemporalType.TIMESTAMP)
private Date runAt;
#Column(name="trials")
private Integer trials;
#OneToOne(mappedBy="result", cascade = {CascadeType.ALL})
private ResultDetails overallStats;
#OneToMany(mappedBy="result", cascade = {CascadeType.ALL})
private List<ResultDetails> resultDetails = new ArrayList<ResultDetails>();
}
ResultDetail.java
#Entity
#Table(name="result_details")
public class ResultDetails extends BaseEntity {
#ManyToOne
#JoinColumn(name = "results_id", nullable=false)
#NotNull
private Result result;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="summarys_id", nullable=true)
private Summary summary;
}
When I create persistent entities from my main as follows:
public static void main (String [] args) {
Result result = new Result();
ResultDetails detail1 = new ResultDetails();
ResultDetails detail2 = new ResultDetails();
Summary s1 = new Summary();
Summary s2 = new Summary();
result.setRunAt(new Date());
result.setTrials(1000000);
detail1.setResult(result);
s1.setMean(3.0);
detail1.setSummary(s1);
result.setOverallStats(detail1);
detail2.setCybervarResult(result);
s2.setMean(11.0);
detail2.setSummary(s2);
result.addDetails(detail2);
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.saveOrUpdate(result);
session.getTransaction().commit();
HibernateUtil.shutdown();
}
It adds the appropriate rows to the tables. However, when I retrieve the data as demonstrated by the following additional main file:
Session session = HibernateUtil.getSessionFactory().openSession();
Result result = session.get(CybervarResult.class, 6);
result.getOverallStats().getSummary();
result.getResultDetails().size();
HibernateUtil.shutdown();
System.out.println(result.getOverallStats().getSummary().getMean());
System.out.println(result.getResultDetails().get(0).getSummary().getMean());
Hibernate is able to correctly populate the 'overallStats' and 'resultDetails' objects. How is it able to differentiate the two rows in the result_details table? As far as I can tell, there is nothing to distinguish the two from each other. Does Hibernate implement hidden tables/rows to manage which member variables correspond to which rows? If I were to create this database from mysql queries instead of through the hibernate API, how would Hibernate know which row should be the 'overallStats' and which rows should belong to the 'resultDetails' collection?
For reference, the rows created look as follows:
mysql> select * from results;
+----+---------------------+---------+
| id | run_at | trials |
+----+---------------------+---------+
| 6 | 2017-11-13 09:27:52 | 1000000 |
+----+---------------------+---------+
mysql> select * from result_details;
+----+------------+-------------+
| id | results_id | summarys_id |
+----+------------+-------------+
| 10 | 6 | 14 |
| 11 | 6 | 15 |
+----+------------+-------------+
hibernate.cfg.xml
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/usersdb</property>
<property name="hibernate.connection.username">test</property>
<property name="hibernate.connection.password">test</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">validate</property>
I have a before insert trigger in MySQL that works when row is inserted directly (through DB client) into database but DOES NOT work through Hibernate ORM.
Some basic info
MySQL 5.6.26 on Debian Jessie 8.6
MySQL Connector Java 5.1.40
Hibernate ORM 5.2.4
the Product table
+----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| prd_no | varchar(6) | YES | UNI | NULL | |
| prd_ty | varchar(20) | NO | | NULL | |
| prd_name | varchar(50) | NO | | NULL | |
| prd_name_short | varchar(10) | NO | | NULL | |
| prd_cat | varchar(20) | NO | | NULL | |
| prd_tax_ty | varchar(20) | NO | | NULL | |
| prd_price_ty | varchar(20) | NO | | NULL | |
| prd_norm_avail | tinyint(3) unsigned | NO | | 1 | |
| ppp_id | int(10) unsigned | YES | MUL | NULL | |
+----------------+---------------------+------+-----+---------+----------------+
My trigger
DELIMITER $$
CREATE TRIGGER tg_product_insPrdNo BEFORE INSERT ON product
FOR EACH ROW
BEGIN
IF NEW.prd_ty = 'ns' THEN
SET NEW.prd_no = fn_getPrdNoNextAI();
END IF;
END $$
DELIMITER ;
Function that gets called by the trigger
DELIMITER //
CREATE FUNCTION fn_getPrdNoNextAI()
RETURNS INTEGER SIGNED
BEGIN
DECLARE last_prd_no INTEGER SIGNED;
SELECT (MAX(CAST(product.prd_no AS SIGNED))) INTO last_prd_no FROM product;
IF last_prd_no IS NULL THEN
SET last_prd_no = 0;
END IF;
RETURN last_prd_no+1;
END //
DELIMITER ;
Java code (abbreviated) for inserting row
Session session = AES_Server.getSessionFactory().openSession();
Transaction tx = null;
int prdID = -1;
try {
tx = session.beginTransaction();
prdID = (int) session.save(prd);
tx.commit();
} catch (HibernateException he) {
if (tx != null)
tx.rollback();
} finally {
session.close();
}
return prdID;
Basically, my DB trigger will only auto-insert value for prd_no field if prd_ty is of value 'ns'. This works fine when inserting directly into the DB but when using hibernate to insert, no value is inserted.
Any pointers would be much appreciated. Cheers.
I am tring the 'not equal' query in hql.
#Override
public Student findStudentsByYear(String year) {
String queryString = "from Student where year<>:year ";
Query query = sessionFactory.getCurrentSession().createQuery(queryString);
query.setParameter("year", year);
return (Student)query.uniqueResult();
}
but it is not working properly.How to write this query correctly
My student table is
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| studentId | bigint(20) | NO | PRI | NULL | auto_increment |
| course | varchar(255) | YES | | NULL | |
| dob | varchar(255) | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
| faculty | varchar(255) | YES | | NULL | |
| firstName | varchar(255) | YES | | NULL | |
| gender | int(11) | YES | | NULL | |
| homeAddress | varchar(255) | YES | | NULL | |
| lastName | varchar(255) | YES | | NULL | |
| linkedIn | varchar(255) | YES | | NULL | |
| university | varchar(255) | YES | | NULL | |
| year | varchar(255) | YES | | NULL | |
| user_userId | bigint(20) | YES | MUL | NULL | |
+-------------+--------------+------+-----+---------+----------------+
I know it's late but if anyone is having similar problem, you can use this:
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.ne("year", year));
List<Student> result = criteria.list();
Or this:
List<Student> result = session.createQuery ("from Student where year!=:year").setParameter("year", year).list();
I'm not sure what the problem is in above example as Samantha did not provide any information what so ever but my guess is that the uniqueResult() is causing trouble because this query returns a list and not one result.
I have a table in my database, which contains sportsresults, and I need to select the last result for a competitor on a specific eventstage from a table.
I have this table:
+----------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------+------+-----+---------+-------+
| EventStageID | int(11) | NO | PRI | NULL | |
| CompetitorID | int(11) | NO | PRI | NULL | |
| Lap | int(11) | NO | PRI | NULL | |
| Time | varchar(255) | YES | | NULL | |
| Status | varchar(255) | YES | | NULL | |
| PitstopCount | int(11) | YES | | NULL | |
| Grid | int(11) | YES | | NULL | |
| FastestLapTime | varchar(255) | YES | | NULL | |
| Substatus | varchar(255) | YES | | NULL | |
| Points | decimal(10,2) | YES | | NULL | |
| Position | int(11) | YES | | NULL | |
| StageType | int(11) | YES | | NULL | |
+----------------+---------------+------+-----+---------+-------+
I can select from the table with normal SQL query like this:
SELECT * FROM
(SELECT EventStageID as esi, CompetitorID as cid, Max(Lap) as MaxLap FROM srt_outright_season_event_stage_result_live WHERE EventStageID = 191666 GROUP BY CompetitorID) as y
LEFT JOIN
(SELECT * FROM srt_outright_season_event_stage_result_live) as x
ON x.CompetitorID = y.cid AND x.Lap = y.MaxLap AND x.EventStageID = y.esi;
Which gives the following result:
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
| esi | cid | MaxLap | EventStageID | CompetitorID | Lap | Time | Status | PitstopCount | Grid | FastestLapTime | Substatus | Points | Position | StageType |
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
| 191666 | 4521 | 0 | 191666 | 4521 | 0 | Finished | NULL | NULL | NULL | 2:00.175 | NULL | NULL | 4 | 5 |
| 191666 | 4524 | 0 | 191666 | 4524 | 0 | Finished | NULL | NULL | NULL | 2:04.053 | NULL | NULL | 10 | 5 |
| 191666 | 4533 | 0 | 191666 | 4533 | 0 | Finished | NULL | NULL | NULL | NULL | NULL | NULL | 13 | 5 |
| 191666 | 4538 | 0 | 191666 | 4538 | 0 | Finished | NULL | NULL | NULL | 2:01.218 | NULL | NULL | 6 | 5 |
| 191666 | 5769 | 0 | 191666 | 5769 | 0 | Finished | NULL | NULL | NULL | 2:00.050 | NULL | NULL | 3 | 5 |
| 191666 | 7135 | 0 | 191666 | 7135 | 0 | Finished | NULL | NULL | NULL | 1:59.431 | NULL | NULL | 1 | 5 |
| 191666 | 7138 | 0 | 191666 | 7138 | 0 | Finished | NULL | NULL | NULL | NULL | NULL | NULL | 18 | 5 |
| 191666 | 7610 | 0 | 191666 | 7610 | 0 | Finished | NULL | NULL | NULL | 1:59.486 | NULL | NULL | 2 | 5 |
+--------+--------+--------+--------------+--------------+------+----------+--------+--------------+------+----------------+-----------+--------+----------+-----------+
I have this Entity class:
#Entity(name = "event_stage_result_live")
public class EventStageResultLive {
#EmbeddedId
private PKEventStageResultLive pkEventStageResultLive;
// Composite PK contains EventStageID, CompetitorID and Lap
#Column(name = "Time")
private String time;
#Column(name = "Status")
private String status;
#Column(name = "PitstopCount")
private Integer pitstopCount;
#Column(name = "Grid")
private Integer grid;
#Column(name = "Position")
private Integer position;
#Column(name = "FastestLapTime")
private String fastestLapTime;
#Column(name = "Substatus")
private String substatus;
#Column(name = "Points")
private Float points;
#Column(name = "StageType")
private StageType stageType;
// getters and setters...
}
I think in SQL you can do something like this. I dont think join is required.
select * from srt_outright_season_event_stage_result_live c
where c.CompetitorID = :competitorID and c.EventStageID = 191666
and c.Lap = (select max(d.lap) from srt_outright_season_event_stage_result_live d
where d.CompetitorID = :competitorID and d.EventStageID = 191666 )
Passed to JPQL is
select e from EventStageResultLive e
where e.pkEventStageResultLive.CompetitorID = :competitorID and c.pkEventStageResultLive.EventStageID = 191666
and e.pkEventStageResultLive.Lap = (select max(d.pkEventStageResultLive.lap) from EventStageResultLive d
where d.pkEventStageResultLive.CompetitorID = :competitorID and d.pkEventStageResultLive.EventStageID = 191666 )
Assuming
public class PKEventStageResultLive{
private int CompetitorID ;
private int EventStageID ;
private int Lap;
}
If the name of the properties are different correct the name in the JPQL
And competitorID as a named parameter.