Invalid object name - java

When doing...
select * from students
I get a "Invalid object name" error. Basically, I think I can see the problem in that the tables are prefixed with an object name rather than just dbo, lets call the schema "test".
So this means....
select * from test.students
The problem I have is that I can't change the SQL code (it's in release, long story) or change the tables. My question is, is there anything I can change in SQL server that will allow me to connect say with a specific SQL server user so I can still run my queries as...
select * from students
Omitting the object name, but still have the object name against the table? I can add another SQL user or something like that no problem.
I'm using Java over the jdbc protocol, so my connection string is something like jdbc:sqlserver://hostname:port;databaseName=db;user=myuser;password=mypassword
Thanks,
David

You're looking for a default schema option, which doesn't exist for a given connection. That is to say that you can't say something like "until I say otherwise, unqualified tables are in the test schema". You can, however, set a default schema for a user. For your example, you'd do
alter user [myuser] with default_schema = [test]

Try to edit the connection string and set your default catalog to your "test" database
<add name="ConnectionString" connectionString="Data Source=server;Initial
Catalog=test;Persist Security Info=True;User ID=user;Password=password;"
providerName="SqlDataClient"/>

Related

HSQL database user lacks privilege or object not found error

I am trying to use hsqldb-2.3.4 to connect from Spring applicastion.
I created data base using the following details
Type : HSQL Database Engine Standalone
Driver: org.hsqldb.jdbcDriver
URL: jdbc:hsqldb:file:mydb
UserName: SA
Password: SA
I created a table named ALBUM under "MYDB" schema
In spring configuration file:
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dbcpDataSource" />
</bean>
<bean id="dbcpDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:file:mydb" />
<property name="username" value="SA" />
<property name="password" value="SA" />
</bean>
And in my spring controller I am doing jdbcTemplate.query("SELECT * FROM MYDB.ALBUM", new AlbumRowMapper());
And It gives me exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT * FROM MYDB.ALBUM]; nested exception is java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: ALBUM
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
If I execute same query through SQL editor of hsqldb it executes fine. Can you please help me with this.
As said by a previous response there is many possible causes. One of them is that the table isn't created because of syntax incompatibility. If specific DB vendor syntax or specific capability is used, HSQLDB will not recognize it. Then while the creation code is executed you could see that the table is not created for this syntax reason. For exemple if the entity is annoted with #Column(columnDefinition = "TEXT") the creation of the table will fail.
There is a work around which tell to HSQLDB to be in a compatible mode
for pgsl you should append your connection url with that
"spring.datasource.url=jdbc:hsqldb:mem:testdb;sql.syntax_pgs=true"
and for mysql with
"spring.datasource.url=jdbc:hsqldb:mem:testdb;sql.syntax_mys=true"
oracle
"spring.datasource.url=jdbc:hsqldb:mem:testdb;sql.syntax_ora=true"
note there is variant depending on your configuration
it could be hibernate.connection.url= or spring.datasource.url=
for those who don't use the hibernate schema creation but a SQL script you should use this kind of syntax in your script
SET DATABASE SQL SYNTAX ORA TRUE;
It will also fix issues due to vendor specific syntax in SQL request such as array_agg for posgresql
Nota bene : The the problem occurs very early when the code parse the model to create the schema and then is hidden in many lines of logs, then the unitTested code crash with a confusing and obscure exception "user lacks privilege or object not found error" which does not point the real problem at all. So make sure to read all the trace from the beginning and fix all possible issues
If you've tried all the other answers on this question, then it is most likely that you are facing a case-sensitivity issue.
HSQLDB is case-sensitive by default. If you don't specify the double quotes around the name of a schema or column or table, then it will by default convert that to uppercase. If your object has been created in uppercase, then you are in luck. If it is in lowercase, then you will have to surround your object name with double quotes.
For example:
CREATE MEMORY TABLE "t1"("product_id" INTEGER NOT NULL)
To select from this table you will have to use the following query
select "product_id" from "t1"
user lacks privilege or object not found can have multiple causes, the most obvious being you're accessing a table that does not exist. A less evident reason is that, when you run your code, the connection to a file database URL actually can create a DB. The scenario you're experiencing might be you've set up a DB using HSQL Database Manager, added tables and rows, but it's not this specific instance your Java code is using. You may want to check that you don't have multiple copies of these files: mydb.log, mydb.lck, mydb.properties, etc in your workspace. In the case your Java code did create those files, the location depends on how you run your program. In a Maven project run inside Netbeans for example, the files are stored alongside the pom.xml.
I had the error user lacks privilege or object not found while trying to create a table in an empty in-memory database.
I used spring.datasource.schema and the problem was that I missed a semicolon in my SQL file after the "CREATE TABLE"-Statement (which was followed by "CREATE INDEX").
I had similar issue with the error 'org.hsqldb.HsqlException: user lacks privilege or object not found: DAYS_BETWEEN' turned out DAYS_BETWEEN is not recognized by hsqldb as a function. use DATEDIFF instead.
DATEDIFF ( <datetime value expr 1>, <datetime value expr 2> )
When running a HSWLDB server. for example your java config file has:
hsql.jdbc.url = jdbc:hsqldb:hsql://localhost:9005/YOURDB;sql.enforce_strict_size=true;hsqldb.tx=mvcc
check to make sure that your set a server.dbname.#. for example my server.properties file:
server.database.0=eventsdb
server.dbname.0=eventsdb
server.port=9005
I was inserting the data in hsql db using following script
INSERT INTO Greeting (text) VALUES ("Hello World");
I was getting issue related to the Hello World object not found and HSQL database user lacks privilege or object not found error
which I changed into the below script
INSERT INTO Greeting (text) VALUES ('Hello World');
And now it is working fine.
Add these two extra properties:
spring.jpa.hibernate.naming.implicit-strategy=
org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
I bumped into kind of the same problem recently. We are running a grails application and someone inserted a SQL script into the BootStrap file (that's the entry point for grails). That script was supposed to be run only in the production environment, however because of bad logic it was running in test as well. So the error I got was:
User lacks privilege or object not found:
without any more clarification...
I just had to make sure the script was not run in the test environment and it fixed the problem for me, though it took me 3 hours to figure it out. I know it is very, very specific issue but still if I can save someone a couple of hours of code digging that would be great.
I was having the same mistake. In my case I was forgetting to put the apas in the strings.
I was doing String test = "inputTest";
The correct one is String test = "'inputTest'";
The error was occurring when I was trying to put something in the database
connection.createStatement.execute("INSERT INTO tableTest values(" + test +")";
In my case, just put the quotation marks ' to correct the error.
In my case the error occured because i did NOT put the TABLE_NAME into double quotes "TABLE_NAME" and had the oracle schema prefix.
Not working:
SELECT * FROM FOOSCHEMA.BAR_TABLE
Working:
SELECT * FROM "BAR_TABLE"
had this issue with concatenating variables in insert statement. this worked
// var1, var3, var4 are String variables
// var2 and var5 are Integer variables
result = statement.executeUpdate("INSERT INTO newTable VALUES ('"+var1+"',"+var2+",'"+var3+"','"+var4+"',"+var5 +")");
In my case the issue was caused by the absence (I'd commented it out by mistake) of the following line in persistence.xml:
<property name="hibernate.hbm2ddl.auto" value="update"/>
which prevented Hibernate from emitting the DDL to create the required schema elements...
(different Hibernate wrappers will have different mechanisms to specify properties; I'm using JPA here)
I had this error while trying to run my application without specifying the "Path" field in Intellij IDEA data source (database) properties. Everything else was configured correctly.
I was able to run scripts in IDEA database console and they executed correctly, but without giving a path to the IDEA, it was unable to identify where to connect, which caused errors.
You have to run the Database in server mode and connect.Otherwise it wont connect from external application and give error similar to user lacks privilege.
Also change the url of database in spring configuration file accordingly when running DB in server mode.
Sample command to run DB in server mode
$java -cp lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:data/mydb --dbname.0 Test
Format of URL in configuration file
jdbc:hsqldb:hsql://localhost/Test
In my case, one of the columns had the name 'key' with the missing #Column(name = "key") annotation so that in the logs you could see the query that created the table but in fact it was not there. So be careful with column names
For what it's worth - I had this same problem. I had a column named 'TYPE', which I renamed to 'XTYPE' and a column named ORDER which I renamed to 'XORDER' and the problem went away.
Yet another reason could be a misspelt field name. If your actual table has an id column named albumid and you'd used album_id, then too this could occur.
As another anwer remarked, case differences in field names too need to be taken care of.
I faced the same issue and found there was more than one PersistenceUnit (ReadOnly and ReadWrite) , So the tables in HSQLDDB created using a schema from one persistence unit resulted in exception(HSQL database user lacks privilege or object not found error) being thrown when accessed from other persistence unit .It happens when tables are created from one session in JPA and accessed from another session
In my case the table MY_TABLE was in the schema SOME_SCHEMA. So calling select/insert etc. directly didn't work. To fix:
add file schema.sql to the resources folder
in this file add the line CREATE SCHEMA YOUR_SCHEMA_NAME;

How to pass SQL query as a context variable in Talend Open Studio job

I am creating a job to pull data from a database to CSV file using talend open studio. There are 100 of tables, the data types and no of columns differ in the tables, I want to pull the data from database tables with a single job and customizable SQL query. I know how to create and use context variables.
If I understood you correctly you should be using tMap's reload at each row -option and defining table names in Excel sheet or in tFixedFlowInput.
tMap settings
Whole job and results
SQL Script:
"SELECT TOP(1) Name, Code from mdm." + (String)globalMap.get("row4.table")
I used Microsoft SQL Server for example but same script works as well with MySQL.
You can simply use a context-variable which you set via the --context_param argument in a tWhicheverDatabaseInput. E.g. define a context variable "my_sql" which you can set in the commandline as
my_job.sh --context_param my_sql="select a,b,c from a_test_table"
and then use context.my_sql as the SQL in you database input component.
However, as garpitmzn already mentioned, you will need dynamic schemas to actually work with this unknown structure in Talend. This feature only exists in the enterprise version.
If the enterprise version is available to you, simply declare a single column of type "Dynamic", which you can pass through the rest of your flow.
Declare a local context say query as type string.
Prepare a context file with variable query: query=select name from employee
Excecute the query: toraclecomponent use context.query
Query is throwing some error when you have where conditions with string type.
Need to investigate more on that. Otherwise it works.

Oracle: Read-only access to the schema for another user?

I have a schema and a user with the same name: products. For development I would like to use it in a read-only mode from a java application. Therefore, I created a new user for the read-only application.
CREATE USER PRODUCTS_READONLY IDENTIFIED BY PRODUCTS_READONLY;
GRANT CREATE SESSION to PRODUCTS_READONLY;
BEGIN
FOR tab IN (SELECT table_name FROM all_tables WHERE owner = 'PRODUCTS') LOOP
EXECUTE IMMEDIATE 'GRANT SELECT ON PRODUCTS.'||tab.table_name||' TO PRODUCTS_READONLY';
END LOOP;
END;
Running the application I got the error that the table did not exist. Searching on the internet for solution, I came across SYNONYM. So I added synonym to the schema:
CREATE SYNONYM PRODUCTS_READONLY FOR PRODUCTS;
Now, I am getting this error in my java application:
ERROR org.hibernate.util.JDBCExceptionReporter - ORA-17074 invalid name pattern.: PRODUCTS_READONLY.PRODUCT_TYPE
What is wrong with my approach?
--UPDATE--
Seems like creating synonyms for schema was removed in 10g (Oracle: is it possible to create a synonym for a schema?). If I create schema for each object in the target schema, I would have to do the same every time a table is added to the target schema or any other changes to the any other objects in the target schema? That sounds cumbersome...
--UPDATE 2--
Seems like a trigger with alter session is a possible solution, but will it make the tables read-only so long the user has only SELECT privilege?
If you have control over the way your application connects (e.g. an initialization statement for your connection pool), all you need to do is run:
ALTER SESSION SET CURRENT_SCHEMA = PRODUCTS;
From that point onward (during the lifetime of the session) any unqualified object name will be searched for in the PRODUCTS schema.
All grants given to PRODUCTS_READONLY will be in effect. The session will run under the credentials (and security restrictions) of the original user used to log in.
If you can not change the way the connection is established or initialized a logon trigger should also accomplish this:
create or replace trigger logon_trg
after logon on database
begin
if (user = 'PRODUCTS_READONLY') then
execute immediate 'alter session set current_schema = products';
end if;
exception
when others then null; -- prevent a login failure due to an exception
end logon_trg;
/
Note that it's crucial to trap any exception, because otherwise a potential error in the executed SQL will effectively log everyone out off the database. So use with care and test it well before putting that into production.
I am not sure you can create a synonym for schema.
But you can create a synonym for every object in the remote schema, e.g.
begin
for c in (select t.table_name from table_privileges t where grantee = 'PRODUCTS_READONLY') loop
execute immediate 'create synonym '||c.table_name||' for PRODUCTS.'||c.table_name;
end loop;
end;
Don't be confused with table_name, it handles all types of objects there.

Changing derbyDB schema 'on the fly' in java client

I have an embeded derbyDB in my app, and I am currently testing my code.
If I send the following SQL code
set current schema [newSchemaName];
from ij then I can set the schema and the response from the DB of
show tables;
will report only the tables that exist in the newSchemaName previously identified (although this doesn't always seem to work!)
If I do a similar thing from java code and then perform a
getCurrentConection.getSchema();
The value returned from the above never proposes the newSchemaName passed in the SQL (although if I use a prepared statement it returns the newSchemaName as expected).
Here is some extra background info...
I have the default database name 'derbyTest' and create 3 other schemas.
Admin
S1
S2
to logically separate/hide information from users that they don't need to know about
I need to change schemas during operation (eg: an admin will change schemas if required to view more 'delicate' info).
To do this I created a method for setSchema(String newSchemaName), that creates the schema (if it doesn't already exist) then connects to it.
However after running the code snippet
/**
*method to change to a given schema
*#param newSchemaName the new schema to change to
/
public void SetSchema(String newSchemaName){
String sql = newSchemaName.toUpperCase();//make sure the newSchemaName is in upper case.
ResultSet rs;
try
{
rs = this.sendQry("select schemaName from sys.sysschemas where schemaname = '" + sql + "'");//does this schema exist in the DB
if (rs.next())
{//the schema already exists
//send some messages to the user about the change of schema
errLog.setDevError(1, "derbyDB schema" +sql +" already exists ");
errLog.add(2, "connecting to " + sql);
//next line create the SQL for changing to the newSchemaName supplied
this.sendSQL("set current schema " + sql);//connect to the schema
//log a message to display the current schema in the DB
//this next log never shows a change to the newSchemaName unless
//I use a prepared statement in my java code.
errLog.add(1, "current DB schema is " + getCurrentConection.getSchema();
}
else{//the schema does not exist
//send a message to the user and output log
errLog.setDevError(1, "derbyDB schema" +sql +" does not exist ");
//code to send message asking if user wants to create the new schema....
}
}//end try
catch{
//catch errors
}
}//end method
If I look at the docs http://db.apache.org/derby/docs/dev/ref/rrefsqlj32268.html for setting the schema my SQL is correct, and the code works if I run directly from ij.
I know that there are some differences between ij and the client side (functions such as describe don't work in the client, you need to fart about with meta data instead).
Is it the same case for the set schema statment. Or does this only work from a prepared statement, which I'm about to test.
If so that begs the question of why I can only change the schema from a prepared statement?
Thoughts and comments greatefully accepted.
David
edit:
A prepared statement works for changing the schema. so now it is only the second question that stands. why the difference between a prepared statement and a normal statement... time for google I think?
edit:
I don't know if it would make a difference but I am on a windows platform, using the standard JDK (6), and eclipse indigo running jUnit test inside eclipse. I can also test on Linux(ubuntu) with opendJDK if it may help to troubleshoot.
I'm not sure what your question is.
You can specify the schema explicitly in your table references, as in:
SELECT * FROM S1.TABLE_NAME
or
UPDATE S2.TABLE_NAME SET COL1=VALUE1
etc.
Or, if you prefer, you can omit the schema name from your table references, saying merely:
SELECT * FROM TABLE_NAME
or
UPDATE TABLE_NAME SET COL1=VALUE1
etc., in which case you will need to establish an implicit schema for those statements, either by issuing a SET SCHEMA statement, or by using the existing default schema, which matches your username when you log in.
I think your question about prepared statements versus non-prepared statements has to do with the fact that, if you don't specify an explicit schema, then the default schema name is established when the statement is prepared.
If it were me, and I cared about what schema I was using, I would specify the schema explicitly in all my table references in all my SQL statements, and then I'd be sure which schema I was using when.

JDBC Change Default Schema

I'm trying to connect to a sql server 2005 database via JDBC.
I get the error:
com.microsoft.sqlserver.jdbc.SQLServerException: The SELECT permission
was denied on the object 'MyTable', database 'MyDatabase', schema
'dbo'.
The schema I use to connect is "MyUser". How do I connect using MyUser as opposed to dbo?
Thanks!
To clear things up: You connect to SQL Server using a user, not a schema. You don't say what version of SQL Server you're connecting to, but it used to be the case that the two were equivalent. As of 2005+, that is no longer true.
dbo is the default schema (think of it as a namespace); what the error message is telling you is the user you are connecting with (If I understand correctly, that's MyUser) does not have permission to SELECT from the MyTable table, which is part of the dbo schema in the MyDatabase database.
The first thing to do is confirm whether or not the user you're connecting with does or does not have SELECT permissions on that table. The second thing to do is, if it doesn't, either give MyUser that permission or use a different user to perform the SELECT statement.
i found that you have to specify your schema in your POJOS definitions.
In my case I got the same trouble using JPA (Entities / Annotations) and I realized that specifing the schema property in the #Table annotation works.
for example:
#Table(name = "address", **schema="*dbo*"**, catalog = "petcatalog")
I hope this helps you.

Categories

Resources