For some reason the query that is generated by hibernate is wrong. I have other tables/classes where the generated query is correct however for one table it is wrong. When I do a trace using MS Management Studio I see the following:
exec sp_prepexec #p1 output,NULL,N'select aprresourc0_.agrtid as agrtid1_14_, aprresourc0_.att_id_1 as att_id_2_14_,
aprresourc0_.att_id_2 as att_id_3_14_, aprresourc0_.att_id_3 as att_id_4_14_, aprresourc0_.att_id_4 as att_id_5_14_,
aprresourc0_.attribute_id as attribut6_14_, aprresourc0_.bflag as bflag7_14_, aprresourc0_.client as client8_14_, ...
from aprresourcepost aprresourc0_
where ...
select #p1
The columns att_id_1, att_id_2, att_id_3 and att_id_4 do not exist in the table or my Java class!
How do I fix this? Why does this happen?
It turns out to have been a simple mistake. I continued to work on the project and the next class I was looking at matched the query I was getting in my problem so I checked the code and found I was referencing the wrong class in my code!
Related
When I try to load an Entity with Hibernate I get the following error in postgres-log:
ERROR: column appuser0_.device_token does not exist at character 35
STATEMENT: select appuser0_.id as id1_27_0_, appuser0_.device_token as device_t2_27_0_,....
The column device_token definitely exists - and if I copy-paste the whole logged statement and execute it in PGAdmin, I get the expected result.
So what do I forget? What is the difference between the Hibernate statement and the manually executed one?
This issue was caused by the multi tenant configuration so that the wrong DataSource has been chosen.
Depending on how you defined the query, the problem might be located somewhere else: For example, HQL Queries are using the "property-names" of the class, not the column names.
And if you have something like:
#Column("device_token")
private String deviceToken;
Then your HQL-Query should target "deviceToken" and not "device_token". We also encountered a similar error once: Hibernate was reporting "user_id" is missing, because we named the property "userId" with the underscored version for the column name only.
This might be not the problem for you but worth double checking it.
<insert id="insert" parameterType="Dto">
INSERT INTO table VALUES
(GeomFromText('POINT(#{latitude} #{longitude})'))
</insert>
I would like to execute above query, however it returns some error
Cause: java.sql.SQLException: Parameter index out of range (12 >
number of parameters, which is 11).
INSERT INTO filtered_user_location VALUES (GeomFromText('POINT(? ?)'))
I think the error means that prepared statement(?) in a single quotation doesn't work.
do you have any good idea?
Thx Mr.Alien for edit
I fixed query like
GeomFromText('POINT(${latitude} ${longitude})')
then it works well
In read out with this tutorial,
http://mybatis.co.uk/
Its seems to do somthing like this. You dint mention any column name in your query.
insert into filtered_user_location
(columnname1,columnname2)
VALUES
(#{latitude},#{longitude});
This is something that I've been scratching my head with - especially since it's infuriating to deal with.
Consider the following code:
String query = "UPDATE ORDERS SET VOLUME=?,CONTRACT_ID=?,PROJECT_ID=?,WORKSITE_ID=?,DROPZONE_ID=?,DESCRIPTION_ID=?,MANAGER_ID=?,DELIVERY_DATE=?,REVISION=REVISION+1) WHERE ID=?";
jdbcTemplate.update(query, orderEntity.getVolume(), orderEntity.getContractNo(), orderEntity.getProjectID(), orderEntity.getWorksiteID(), orderEntity.getDropzoneID(), orderEntity.getDescriptionID(), orderEntity.getManagerID(), orderEntity.getDeliveryDate(), id);
We can see that the SQL query is incorrect - and will therefore throw some SQL error but one might have missed that. Spring will (for me) throw a QueryTimeoutException in response to this. I'm sort of okay with that but it's not helpful.
Now let's try
String query = "INSERT INTO ORDERS(ID,REISION,CONTRACT_ID,PROJECT_ID,WORKSITE_ID,DROPZONE_ID,DESCRIPTION_ID,MANAGER_ID,VOLUME,DELIVERY_DATE) VALUES(?,?,?,?,?,?,?,?,?,?)";
jdbcTemplate.update(query, id, revision, etc);
Another spelling mistake that's easily missed - REVISION is misspelled as REISION) Spring throws another QueryTimeoutException again. This now means that if I get that exception I don't actually know what it is. Is it a syntax error? Is it a column spelling error? Is it the (much harder to notice) fact that the foreign key constraint not being followed?
While debugging, this is quite possibly the most infuriating thing ever - all I know is that my query failed to run. How can I get something useful? Is there something I've not added to my pom.xml file?
EDIT:
Here's a nicer example. I have a DESCRIPTIONS table, with an ID, REVISION and TEXT column. All of those are marked as not being nullable.
DescriptionEntity descriptionEntity = new DescriptionEntity("newDesc", 1, null);
String query = "INSERT INTO DESCRIPTIONS (ID,REVISION,TEXT) VALUES(?,?,?)";
jdbcTemplate.update(query, descriptionEntity.getID(), 1, descriptionEntity.getText());
That will also throw a query timeout exception, when running the query in mysql gives me ERROR 1048 (23000): Column 'TEXT' cannot be null
This is, to put it politely, a bit of a pain.
It's not a spelling mistake in the first example, as you left out the opening paren. I would say this isn't an issue with Spring or JDBC, but rather your DB is trying to process the SQL, waiting for more input or something, and never returning.
In the second one, I am not sure what you are talking about since I don't know the table design. I have to assume what you mean is ID is not unique? Again, I wouldn't blame Spring or JDBC, maybe the drive, most likely the database server.
Keep in mind, in a lot of cases, the way SQL is handled in the user Client UI is not the same as how it gets handled through JDBC. For instance, in SQL Server the SQL is set as a string, the passed in parameters set as variables, and it uses sp_executesql() to run it. I discovered that when I had a report that ran PERFECTLY fine through SQL Studio Manager client, but blew up when I ran it live because the query plan optimizer took a different path due to the differences in how the SQL was ran.
This is quite possibly the most stupid error I've ever come across: the issue was in how Maven resolved all the dependencies.
The requirement for Spring Security was placed before the JDBC requirement. That made Spring Security pull down org.springframework:spring-tx:jar:3.0.7.RELEASE:compile which satisfied the dependency for JDBC. Moving the JDBC requirement up meant JDBC pulled down org.springframework:spring-tx:jar:3.2.2.RELEASE:compile.
I am attempting to use zxJDBC to connect to a database running on SQL Server 2008 R2 (Express) and call a stored procedure, passing it a single parameter. I am using jython-standalone 2.5.3 and ideally do not want to have to install additional modules.
My test code is shown below.
The database name is CSM
Stored Procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE dbo.DUMMY
-- Add the parameters for the stored procedure here
#carrierId VARCHAR(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO dbo.carrier (carrierId, test)
VALUES (#carrierId, 'Success')
END
GO
Jython Script:
from com.ziclix.python.sql import zxJDBC
conn = None
try :
conn = zxJDBC.connect('jdbc:sqlserver://localhost\SQLEXPRESS', 'sa', 'password', 'com.microsoft.sqlserver.jdbc.SQLServerDriver')
cur = conn.cursor()
cur.callproc(('CSM','dbo','DUMMY'), ['carrier1'])
conn.commit()
except Exception, err :
print err
if conn:
conn.rollback()
finally :
if conn :
conn.close()
By using cur.execute() I have been able to verify that the above is successfully connecting to the database, and that I can query against it. However, I have thus far been unable to successfully call a stored procedure with parameters.
The documentation here(possibly out of date?) indicates that callproc() can be called with either a string or a tuple to identify the procedure. The example given -
c.callproc(("northwind", "dbo", "SalesByCategory"), ["Seafood", "1998"], maxrows=2)
When I attempt to use this method, I receive the following error
Error("Could not find stored procedure 'CSM.DUMMY'. [SQLCode: 2812], [SQLState: S00062]",)
It would appear that zxJDBC is neglecting to include the dbo part of the procedure identifier.
If I instead call callproc with "CSM.dbo.DUMMY" as the first argument then I receive this error
Error('An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. [SQLCode: 1038], [SQLState: S0004]',)
Using a profiler on the database whilst running my script shows that in the second case the following SQL is executed:
use []
go
So it would seem that when using a single string to identify the procedure, the database name is not correctly parsed out.
One of my trial and error attempts to fix this was to call callproc as follows:
cur.callproc(('CSM', '', 'dbo.DUMMY'), ['carrier1'])
This got me only as far as
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
In this case what I think is happening is that zxJDBC attempts to call a system stored procedure (sp_proc_columns) to determine the required parameters for the stored procedure I want to call. My guess is that with the procedure identifier in the incorrect format above, zxJDBC does not get a valid/correct return and assumes no parameters are required.
So basically I am not a bit stuck for ideas as to how to get it to
Use the correct database name
Correctly determine the required parameters using sp_proc_columns
Call my stored procedure with the correct name
all at the same time.
I do have a workaround, which is to use something like
cur.execute('EXEC CSM.dbo.DUMMY ?', ['carrier1'])
However I feel like callproc() is the correct solution, and would likely produce cleaner code when I come to call stored procedures with large numbers of parameters.
If anyone can spot the mistake(s) that I am making, or knows that this is not ever going to work as I think then any input would be much appreciated.
Thanks
Edit
As suggested by i-one, I tried adding cur.execute('USE CSM') before calling my stored procedure (also removing the database name from the procedure call). This unfortunately produces the same Object or Column missing error as above. The profiler shows USE CSM being executed, followed by USE [] so it seems that callproc() always fires a USE statement before the procedure itself.
I have also experimented with turning on/off autocommit, to no avail.
Edit 2
Further information following comments/suggested solutions:
"SQLEXPRESS" in my connection string is the database instance name.
Using double quotes instead of single has no effect.
Including the database name in the connection string (via ;databaseName=CSM; as specified here) and omitting it from the callproc() call leads to the original error with a USE [] statement being fired.
Using callproc(('CSM', 'dbo', 'dbo.DUMMY'), ['carrier1']) gives me some progress but results in the error
Error("Procedure or function 'DUMMY' expects parameter '#carrierId', which was not supplied. [SQLCode: 201], [SQLState: S0004]",)
I'll attempt to investigate this further
Edit 3
Based on the queries I could see zxJDBC firing, I manually executed the following against my database:
use CSM
go
exec sp_sproc_columns_100 N'dbo.DUMMY',N'dbo',N'CSM',NULL,N'3'
go
This gave me an empty results set, which would seem to explain why zxJDBC isn't passing any parameters to the stored procedure - it doesn't think it needs to. I have yet to figure out why this is happening though.
Edit 4
To update the above, the empty result set is because the call should be
exec sp_sproc_columns_100 N'DUMMY',N'dbo',N'CSM',NULL,N'3'
This unfortunately brings me full circle as I can't remove the dbo owner from the stored procedure name in my callproc() call or the procedure won't be found at all.
Edit 5
Table definition as requested
CREATE TABLE [dbo].[carrier](
[carrierId] [varchar](50) NOT NULL,
[test] [varchar](50) NULL
) ON [PRIMARY]
Though completely unaware of the technologies used here (unless some minor knowledge of SQL Server), I will attempt an answer (please forgive me if my jython syntax is not correct. I am trying to outline possibilities here not exact code)
My first approach (found at this post) would be to try:
cur.execute("use CSM")
cur.callproc(("CSM","dbo","dbo.DUMMY"), ["carrier1"])
This must have to do with the fact that sa users always have the dbo as a default schema (described at this SO post)
If the above does not work I would also try to use the CSM database name in the JDBC url (this is very common when using JDBC for other databases) and then simply call one of the two below.
cur.callproc("DUMMY", ["carrier1"])
cur.callproc("dbo.DUMMY", ["carrier1"])
I hope this helps
Update: I quote the relevant part of the link that you can't view
>> Program calls a Stored Procedure - master.dbo.xp_fixeddrives on MS SQL Server
from com.ziclix.python.sql import zxJDBC
def getConnection():
url = "${DBServer.Url}"
user= "${DBServer.User}"
password = "${DBServer.Password}"
driver = "${DBServer.Driver}"
con = zxJDBC.connect(url, user, password, driver)
return con
try:
conn = getConnection()
print 'Connection successful'
cur = conn.cursor()
cur.execute("use master")
cur.callproc(("master", "dbo", "dbo.xp_fixeddrives"))
print cur.description
for a in cur.fetchall():
print a
finally:
cur.close()
conn.close()
print 'Connection closed'
The error you get when you specified the call function like above suggests that the parameter is not passed correctly. So please modify your stored procedure to take a default value and try to call with passing params = [None]. If you see that the call succeeds we must have done something right as far as specifying the database is concerned.
Btw: the most recent documentation suggests that you should be able to access it with your syntax.
As outlined in comments callproc will work only with SELECT. Try this approach instead:
cur.execute("exec CSM.dbo.DUMMY #Param1='" + str(Param1) + "', #carrierId=" + str(carrierID))
Please see this link for more detail.
I need to be able to refer to a table on a different schema, using OpenJPA to access a Sybase db.
So, for example, I need to select as follows:
SELECT name FROM SHARE.dbo.PROVINCE;
However, the generated SQL is:
SELECT name FROM "SHARE.dbo".PROVINCE;
which Sybase rejects. Without the quotes it works fine.
I'm using the following annotations on the class:
#Entity
#Table(name="PROVINCE", schema="SHARE.dbo")
using schema="SHARE" doesn't work, although it generates the sql without any quotes. (Sybase requires schema.owner.table, so SCHEMA.PROVINCES is an unknown object)
Any thoughts on how to resolve this issue?
Try concatenating the schema to the table name: #Table(name="SHARE.dbo.PROVINCE")
This is a bit of a shot in the dark, but you could try to disable delimited identifier support?
openjpa.DBDictionary=sybase(SupportsDelimitedIdentifiers=false)