How to execute an update via SQLQuery in Hibernate - sql

I need to update a joined sub-class. Since Hibernate doesn't allow to update joined sub-classes in hql or named-query I want to do it via SQL. I also can't use a sql named-query because updates via named-query are not supported in Hibernate.
So I decided to use a SQLQuery. But Hibernate complaints about not calling addScalar():
org.hibernate.QueryException: addEntity() or addScalar() must be called on a sql query before executing the query.
Are updates returning the number of rows affected and how is named that column?
Are there any other ways to do an update on a joined sub-class in hibernate?
Here is a brief example of what i'm trying to do:
<hibernate-mapping>
<class name="example.NiceClass" table="NICE_CLASS">
<meta attribute="class-code"></meta>
<id name="id" type="java.lang.Long">
<column name="NICE_CLASS_ID" precision="8" />
<generator class="sequence">
<param name="sequence">NICE_CLASS_SEQ</param>
</generator>
</id>
</class>
</hibernate-mapping>
<hibernate-mapping package="example">
<joined-subclass name="SubJoinedClass" table="SUB_JOINED_CLASS"
extends="NiceClass">
<key column="NICE_CLASS_ID" foreign-key="NICE_JOINED_ID_FK"/>
<property name="name" type="string" not-null="false">
<column name="NAME" >
<comment>name</comment>
</column>
</property>
</joined-subclass>
</hibernate-mapping>
Thanks in advance!
So I want to do a:
update SubJoinedClass set name = 'newName'

How do you execute the update query ? What method do you call to execute it ? Do you call 'ExecuteUpdate' ?
And why do you think that you cannot execute an update query on a subclass using HQL ? AFAIK, it is possible.

Related

Is this possible to create liquibase variable from SQL query?

In liquibase there is a possibility to define <property>, but it's constant.
Is there any ability to define some variable for <databaseChangeLog>, which is the result from SQL query?
<databaseChangeLog>
<!-- something like this -->
<property name="variable" query="SELECT id FROM Table WHERE name='test'" type="SQL"/>
<changeSet>
<update tableName="Table">
<column name="columnName" value='text'/>
<!-- and below use ${variable} -->
<where>id="${variable}</where>
</update>
</changeSet>
</databaseChangeLog>

how to execute only specific changesets in liquibase which are unread?

I have added some new changesets in an existing changelog file and want to execute only 2 among the new inserted ones. When I give the update command in liquibase it updates all the unread changesets and updates the database. But I want to execute only 2 among these newly inserted changesets in the changelog file. Is there any way of doing this in liquibase? If yes how is it possible?
One way you could do this is to mark the relevant changesets with a label, and then use that label in your liquibase update command.
This blog post on labels describes their use.
Here is an example that matches what you described in your comment below.
changelog
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet id="1" author="steve" labels="labelOne">
<createTable tableName="tableOne">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
<changeSet id="2" author="steve" labels="labelTwo">
<comment>Creating table "tableTwo"</comment>
<createTable tableName="tableTwo">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
<changeSet id="3" author="steve" labels="labelThree">
<comment>Creating table "tableThree"</comment>
<createTable tableName="tableThree">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false" />
</column>
</createTable>
</changeSet>
</databaseChangeLog>
command execution
If you wanted to update and only create table one, you would use this command (if you are using the command line, and assuming that you have a liquibase.properties file that specifies all the connection information, etc.)
liquibase --changeLogFile=changelog.xml --labels=labelOne update
If you wanted to apply two changesets, you would use a command like this:
liquibase --changeLogFile=changelog.xml --labels="labelOne and labelTwo" update

Liquibase - generate table names in lowercase

I am using Liquibase 3.2.0 to perform an upgrade on an Oracle DB. All the existing table names in my schema are in lowercase
My problem is, when I use Liquibase to run a changeSet, the table names are generated in upper-case.
A typical entry in my changeSet looks as follows:
<changeSet author="me (generated)" id="1403006263048-2">
<createTable tableName="batch_job">
<column name="id" type="number">
<constraints nullable="false" primaryKey="true" primaryKeyName="batch_jobPK"/>
</column>
<column name="version" type="number">
<constraints nullable="false"/>
</column>
<column name="execution_time_stamp" type="timestamp">
<constraints nullable="false"/>
</column>
<column name="reference_region" type="varchar2(5)">
<constraints nullable="false"/>
</column>
<column name="trigger_description" type="varchar2(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
However, the resulting table name is: BATCH_JOB
I have tried setting an attribute objectQuotingStrategy="QUOTE_ALL_OBJECTS" in the databaseChangeLog element, with no success.
Is there a way to achieve what I want? I am familiar with the advice offered in Liquibase/PostgreSQL: how to preserve table case correctly?
Any help would be much appreciated. Thanks!
It looks like a bug in how Liquibase is handling case standardization. Could you log an issue at liquibase.jira.com?
For now, the easiset approach would be to use a <modifySql> block to fix the case of the table where it is a problem. Or just fall back on the <sql> tag.
Thanks Nathan, lowercase issue is resolved by using <modifysql> as
<modifySql>
<replace replace="filter" with="FILTER"/>
</modifySql>

Using NHibernate to insert into view

If one would want to insert into a view, what would be required to setup on NHibernate to allow this.
Neither
<generator class="identity" />
nor
<generator class="native" />
allows insert.
Error I get when I try this is either "Null id" or "Null identifier".
You can not insert, update or delete from a view even with regular SQL commands, nor with NHiberanate. Views are designed for read only purposes.
You should model your class from the original tables in a similar fashion as the view and then you could do any CRUD operation on it.
I have never done this but have you tried assigned:-
<generator class="assigned" />
Any modifications, including UPDATE, INSERT, and DELETE statements,
must reference columns from only one base table.
See here MSDN for more info
And there is one more thing if you use assigned, you have to explicitly specify to NHibernate if the object should be saved or updated by calling either the Save() or Update() method of the ISession.

NHibernate not dropping foreign key constraints

I'm new to NHibernate, so this is probably my mistake, but when I use:
schema.Create(true, true);
I get:
SchemaExport [(null)]- There is already an object named 'XXX' in the database.
System.Data.SqlClient.SqlException: There is already an object
named 'XXX' in the database.
I grabbed the SQL code nHibernate was using, ran it directly from MSSMS, and recieved similar errors. Looking into it, the generated code is not properly dropping the foreign key constraints. The drop looks like this:
if exists (select 1 from sysobjects where id = OBJECT_ID(N'dbo[FK22212EAFBFE4C58]')
AND parent_obj = OBJECT_ID('YYY'))
alter table dbo.YYY drop constraint FK22212EAFBFE4C58
Doing a "select OBJECT_ID(N'dbo[FK22212EAFBFE4C58]')" I get null. If I take out the "dbo" (i.e. "select OBJECT_ID(N'[FK22212EAFBFE4C58]')") then the ID is returned.
So, my question is, why is nHibernate adding the dbo, and why does that prevent the object from being returned (since the table owning the constraint is dbo.XXX)
One of my mapping files:
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping namespace="CanineApp.Model" assembly="CanineApp.Model" xmlns="urn:nhibernate-mapping-2.2">
<class name="MedicalLog" table="MedicalLog" schema="dbo">
<id name="MedicalLogID" type="Int64">
<generator class="identity" />
</id>
<property name="InvoiceAmount" type="Decimal" not-null="true" />
...
<many-to-one name="Canine" class="Canine" column="CanineID" not-null="true" fetch="join" />
<many-to-one name="TreatmentCategory" class="TreatmentCategory" column="TreatmentCategoryID" not-null="true" access="field.camelcase-underscore" />
</class>
</hibernate-mapping>
Answer: .
It's probably a bug. There was an entry for this exact issue for SQL Server 2005. It doesn't appear to have been flagged for SQL 2000, so I'll either create a bug report or fix it.