org.postgresql.util.PSQLException: ERROR: syntax error at or near "user" - postgresql

<dataset>
<user id="1" created_date='2017-01-01 00:00:00' email="" user_name="root"/>
</dataset>
xml above gives me error. The problem is i have reserved word for user. how can I solve this. any links?
updated
I am using spring boot, spring data jpa, spring-test-dbunit, dbunit, postgresql

According to this forum https://sourceforge.net/p/dbunit/mailman/message/20643023/ it doesn’t seem like DBUnit has a way to “quote” the table name. But you can configure DatabaseDataSourceConnectionFactoryBean if you do not want to rename tables for some reason or working with legacy database
#Configuration
public class Custom.... {
#Autowired
private DataSource dataSource;
#Bean
public DatabaseConfigBean dbUnitDatabaseConfig() {
DatabaseConfigBean dbConfigBean = new DatabaseConfigBean();
// dbConfigBean.setDatatypeFactory(new PostgresqlDataTypeFactory());
dbConfigBean.setQualifiedTableNames(true);
return dbConfigBean;
}
#Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() {
DatabaseDataSourceConnectionFactoryBean databaseDataSourceConnectionFactoryBean = new DatabaseDataSourceConnectionFactoryBean(dataSource);
databaseDataSourceConnectionFactoryBean.setDatabaseConfig(dbUnitDatabaseConfig());
return databaseDataSourceConnectionFactoryBean;
}
}
After setting true to qualifiedTableNames you should give full name for ur tables in xml
<public.user id="1" created_date='2017-01-01 00:00:00' email="root#demo.io" password="your password" username="root"/>

Related

Spring Boot ShedLock "relation "shedlock" does not exist"

I added ShedLock to my project to prevent working of scheduled job more than one time. I configured it like below but I'm getting
"org.postgresql.util.PSQLException: ERROR: relation "shedlock" does not exist" error.
This is lockProviderBean:
#Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withJdbcTemplate(new JdbcTemplate(dataSource))
.usingDbTime()
.build()
);
}
This is scheduled job:
#Scheduled(cron = "${cronProperty:0 00 23 * * *}")
#SchedulerLock(name = "schedulerLockName")
public void scheduledJob() {
..............
}
I added these notations to my class which contains schduledJob method:
#EnableScheduling
#Component
#Configuration
#EnableSchedulerLock(defaultLockAtMostFor = "2m")
I'm using Spring Data to do database operations and using these properties:
spring.datasource.url = jdbc:postgresql://ip:port/databaseName?currentSchema=schemeName
spring.datasource.driver-class-name = org.postgresql.Driver
spring.jpa.database = postgresql
spring.datasource.platform = postgresql
spring.datasource.hikari.maximum-pool-size=5
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.username = username
spring.datasource.password = password
You have to create the table as described in the documentation.
maybe this is what you are missing:
If you need to specify a schema, you can set it in the table name
using the usual dot notation new JdbcTemplateLockProvider(datasource,
"my_schema.shedlock")
I face this problem too even though shedlock table has been created.
Workarounds for this is by
Setting pg's user default schema using ALTER ROLE YourPgUser SET search_path TO ... , or
Specifing shedlock schema on LockProvider bean
#Bean
public LockProvider getLockProvider(#Autowired JdbcTemplate jdbcTemplate) {
jdbcTemplate.execute("SET search_path TO domaindbschema");
return new JdbcTemplateLockProvider(jdbcTemplate);
}
or another style
#Bean
public LockProvider getLockProvider(#Autowired JdbcTemplate jdbcTemplate) {
return new JdbcTemplateLockProvider(jdbcTemplate, "domaindbschema.shedlock");
}

spring boot + hibernate table names queried in lower case

I'm new to Spring boot and hibernate.
Below is my application prop file and the naming strategy implementation file.
When I try to push data to DB the below exception occurs ERROR: relation "nickname" does not exist.
I want access table name and column name always in uppercase.
Please help me to understand what went wrong.
NickName.java
#Entity
#Table(name="NICKNAME")
public class NickName {
application.properties
spring.datasource.url=jdbc:postgresql://192.168.239.129:5432/maindb
spring.datasource.username=pgdbuser
spring.datasource.password=pgdbuser
spring.jpa.generate-ddl=false
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL82Dialect
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
PhysicalNamingStrategyImpl.java
import java.io.Serializable;
import org.apache.commons.lang.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl implements Serializable{
public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
#Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
String nameModified = StringUtils.upperCase(name.getText());
// Do whatever you want with the name modification
return new Identifier(nameModified, name.isQuoted());
}
#Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
String nameModified = StringUtils.upperCase(name.getText());
// Do whatever you want with the name modification
return new Identifier(nameModified, name.isQuoted());
}
}
Exception:
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:242) ~[spring-orm-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225) ~[spring-orm-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527) ~[spring-orm-5.0.5.RELEASE.jar:5.0.5.RELEASE]
......
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
.......
Caused by: org.postgresql.util.PSQLException: ERROR: relation "nickname" does not exist
Position: 460
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2433) ~[postgresql-42.2.2.jar:42.2.2]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2178) ~[postgresql-42.2.2.jar:42.2.2]
Update 1: changed app.prop file as below
spring.datasource.url=jdbc:postgresql://192.168.239.129:5432/maindb
spring.datasource.username=pgdbuser
spring.datasource.password=pgdbuser
spring.jpa.generate-ddl=false
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect
spring.jpa.hibernate.naming.physical-strategy=com.theroot.rester.PhysicalNamingStrategyImpl
Note :
In my sql client just now checked
select * from "NICKNAME"; --Works
select * from NICKNAME; --doesn't Work
This should work :
1) Get rid of PhysicalNamingStrategyImpl.java
2) Make changes in application.properties as below :
spring.jpa.properties.hibernate.dialect =
org.hibernate.dialect.PostgreSQL95Dialect spring.jpa.hibernate.naming.implicit-
strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
3) In #Table add schema as well. ie., #Table(name="table", schema="schemaname")
This worked for me with Postgresql 10 with Hibernate 5.x and Spring Boot 2.1.x. If you are using an older version of Postgresql, then use appropriate PostgreSqlxxDialect from Spring.

DBUnit with Postgresql and case sensitivity of column names - how does it work?

I'm trying to write integration tests for our Spring Boot app. We want to use spring-test-dbunit and dbunit to setup and teardown test data on a Postgresql 9.4.2 database with an empty schema.
After struggling with case insensitive table names, which I could easily solve by setting the DBUnit config property caseSensitiveTableNames to true, I am now having the exact same issue with column names, but I cannot figure out how to make DBUnit understand that Postgresql doesn't go well with upper case.
Here's my (simplified) dataset:
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<customer_status status_id="0" descripton="description" />
</dataset>
And here's my basic test case so far:
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, DbUnitTestExecutionListener.class })
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = IntegrationTestConfig.class)
#WebAppConfiguration
#IntegrationTest("server.port:0")
#DbUnitConfiguration(databaseConnection="dbUnitDatabaseConnection")
#DatabaseSetup("classpath:datasets/authentication/oauth_setup.xml")
#DatabaseTearDown(type = DatabaseOperation.DELETE_ALL, value = { "classpath:datasets/authentication/oauth_setup.xml" })
#DirtiesContext
public class OauthIntegrationTest {
#Value("${local.server.port}")
int port;
#Test
public void thatStuffIsHappening() {
//here be stuff (test fails on dbunit setup)
}
}
And finally this is my DBUnit configuration so far:
#Import({ ControllerConfig.class, PersistenceConfig.class })
public class IntegrationTestConfig extends App {
#Autowired
DataSource dataSource;
#Bean
public DatabaseConfigBean dbUnitDatabaseConfig() {
final DatabaseConfigBean dbConfig = new DatabaseConfigBean();
dbConfig.setDatatypeFactory(new PostgresqlDataTypeFactory());
dbConfig.setCaseSensitiveTableNames(true);
return dbConfig;
}
#Bean
public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection() {
final DatabaseDataSourceConnectionFactoryBean connection = new DatabaseDataSourceConnectionFactoryBean();
connection.setDataSource(this.dataSource);
connection.setDatabaseConfig(this.dbUnitDatabaseConfig());
connection.setSchema("public");
return connection;
}
}
Running the test ends up with this error:
org.dbunit.dataset.NoSuchColumnException: customer_status.DESCRIPTON - (Non-uppercase input column: descripton) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
Which is correct, because all column names in PSQL are in lower case. Why is DBUnit turning them to upper case and is there a way to prevent that?
I've tried to google it, but the only thing matching my problem so far was this, but I really don't like reverting to old versions.
Any hints? I can't believe that this is a serious problem and not just me overlooking something...
Oh my - this has just been a major facepalm issue. There was a typo in my setup.xml file. Instead of "description" I wrote "descripton".
Now it works and there is nothing wrong with anything except my typing and reading skills. ;)

"Type class is not known to the MapperRegistry" in MyBatis

My Problem
I'm getting the error Type class myPackage.MyClass is not known to the MapperRegistry.
I successfully acquired a session, and upon debugging I can see that it otherwise appears to be configured correctly so the interface association seems to be working; therefor I'm confident this error is distinct from the stack-overflow-suggested Type interface is not known... question.
I'm new to myBatis but from the documentation I understood that the following was all that was required to get resultType auto-mapping to work.
Update: This also happens when mapping the mapper resources by xml file instead of by class.
My Mapper
public interface MyClassMapper{
MyClass getMyClass(Integer id);
}
My Model
public class MyClass{
private String itemValue;
public String getItemValue() {
return itemValue;
}
public void setItemValue(String itemValue) {
this.itemValue = itemValue;
}
}
My Sql Map
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="myPackage.orm.sqlMap.MyClassMapper" >
<select id="getMyClass" resultType="myPackage.MyClass" >
select itemValue
from SOME_TABLE
WHERE id = #{id}
</select>
</mapper>
My mybatis-config.xml
...
<mappers>
<mapper class="myPackage.MyClass" />
</mappers>
...
Fixed:
public MyClass getMyClassValue(Integer id) throws Exception{
SqlSession session = MyBatisSessionFactory.openSession();
MyClassMapper mapper = (MyClassMapper) session.getMapper(MyClass.class);
return mapper.getMyClass(id);
}
Here is the code I was using to execute the query, discovered that I was looking up the mapper in the mapper registry by the model class name, rather than the mapper interface name. Works just fine now.
In your mapper.xml file mapper's namespace should be the path to the mapper interface.
for example:
<mapper namespace="com.mapper.LineMapper">
<select id="selectLine" resultType="com.jiaotong114.jiaotong.beans.Line">
select * from bus_line where id = #{id}
</select>
</mapper>
your mapper interface should be in com.mapper package and the name of it is LineMapper.
hope help.
I solved this issue by adding the mapper XML to the mybatis xml configuration file
<mappers>
<mapper resource="com/java/Mapper.xml"/>
</mappers>

How to consume a complex object from a sproc using WCF Data Services / OData?

Using WCF Data Services (and the latest Entity Framework), I want to return data from a stored procedure. The returned sproc fields do not match 1:1 any entity in my db, so I create a new complex type for it in the edmx model (rather than attaching an existing entity):
Right-click the *.edmx model / Add / Function Import
Select the sproc (returns three fields) - GetData
Click Get Column Information
Add the Function Import Name: GetData
Click Create new Complex Type - GetData_Result
In the service, I define:
[WebGet]
public List<GetData_Result> GetDataSproc()
{
PrimaryDBContext context = new PrimaryDBContext();
return context.GetData().ToList();
}
I created a quick console app to test, and added a reference to System.Data.Services and System.Data.Services.Client - this after running Install-Package EntityFramework -Pre, but the versions on the libraries are 4.0 and not 5.x.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Services.Client;
using ConsoleApplication1.PrimaryDBService;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataServiceContext context = new DataServiceContext(new Uri("http://localhost:50100/PrimaryDataService1.svc/"));
IEnumerable<GetData_Result> result = context.Execute<GetData_Result>(new Uri("http://localhost:50100/PrimaryDataService1.svc/GetDataSproc"));
foreach (GetData_Result w in result)
{
Console.WriteLine(w.ID + "\t" + w.WHO_TYPE_NAME + "\t" + w.CREATED_DATE);
}
Console.Read();
}
}
}
I didn't use the UriKind.Relative or anything else to complicate this.
When I navigate in the browser to the URL, I see data, but when I consume it in my console app, I get nothing at all.
Adding tracing to the mix:
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\temp\WebWCFDataService.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
... and opening using the Microsoft Service Trace Viewer, I see two idential warnings:
Configuration evaluation context not found.
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>524312</EventID>
<Type>3</Type>
<SubType Name="Warning">0</SubType>
<Level>4</Level>
<TimeCreated SystemTime="2012-04-03T14:50:11.8355955Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{66f1a241-2613-43dd-be0c-341149e37d30}" />
<Execution ProcessName="WebDev.WebServer40" ProcessID="5176" ThreadID="10" />
<Channel />
<Computer>MyComputer</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Warning">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.EvaluationContextNotFound.aspx</TraceIdentifier>
<Description>Configuration evaluation context not found.</Description>
<AppDomain>fd28c9cc-1-129779382115645955</AppDomain>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
So why am I able to see data from the browser, but not when consumed in my app?
-- UPDATE --
I downloaded the Microsoft WCF Data Services October 2011 CTP which exposed DataServiceProtocolVersion.V3, created a new host and client and referenced Microsoft.Data.Services.Client (v4.99.2.0). Now getting the following error on the client when trying iterate in the foreach loop:
There is a type mismatch between the client and the service. Type
'ConsoleApplication1.WcfDataServiceOctCTP1.GetDataSproc_Result' is an
entity type, but the type in the response payload does not represent
an entity type. Please ensure that types defined on the client match
the data model of the service, or update the service reference on the
client.
I tried the same thing by referencing the actual entity - works fine, so same issue.
Recap: I want to create a high-performing WCF service DAL (data access layer) that returns strongly-typed stored procedures. I initially used a "WCF Data Services" project to accomplish this. It seems as though it has its limitations, and after reviewing performance metrics of different ORM's, I ended up using Dapper for the data access inside a basic WCF Service.
I first created the *.edmx model and created the POCO for my sproc.
Next, I created a base BaseRepository and MiscDataRepository:
namespace WcfDataService.Repositories
{
public abstract class BaseRepository
{
protected static void SetIdentity<T>(IDbConnection connection, Action<T> setId)
{
dynamic identity = connection.Query("SELECT ##IDENTITY AS Id").Single();
T newId = (T)identity.Id;
setId(newId);
}
protected static IDbConnection OpenConnection()
{
IDbConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["PrimaryDBConnectionString"].ConnectionString);
connection.Open();
return connection;
}
}
}
namespace WcfDataService.Repositories
{
public class MiscDataRepository : BaseRepository
{
public IEnumerable<GetData_Result> SelectAllData()
{
using (IDbConnection connection = OpenConnection())
{
var theData = connection.Query<GetData_Result>("sprocs_GetData",
commandType: CommandType.StoredProcedure);
return theData;
}
}
}
}
The service class:
namespace WcfDataService
{
public class Service1 : IService1
{
private MiscDataRepository miscDataRepository;
public Service1()
: this(new MiscDataRepository())
{
}
public Service1(MiscDataRepository miscDataRepository)
{
this.miscDataRepository = miscDataRepository;
}
public IEnumerable<GetData_Result> GetData()
{
return miscDataRepository.SelectAllData();
}
}
}
... and then created a simple console application to display the data:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Service1Client client = new Service1Client();
IEnumerable<GetData_Result> result = client.GetData();
foreach (GetData_Result d in result)
{
Console.WriteLine(d.ID + "\t" + d.WHO_TYPE_NAME + "\t" + d.CREATED_DATE);
}
Console.Read();
}
}
}
I also accomplished this using PetaPOCO, which took much less time to setup than Dapper - a few lines of code:
namespace PetaPocoWcfDataService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class Service1 : IService1
{
public IEnumerable<GetData_Result> GetData()
{
var databaseContext = new PetaPoco.Database("PrimaryDBContext"); // using PetaPOCO for data access
databaseContext.EnableAutoSelect = false; // use the sproc to create the select statement
return databaseContext.Query<GetData_Result>("exec sproc_GetData");
}
}
}
I like how quick and simple it was to setup PetaPOCO, but using the repository pattern with Dapper will scale much better for an enterprise project.
It was also quite simple to create complex objects directly from the EDMX - for any stored procedure, then consume them.
For example, I created complex type return type called ProfileDetailsByID_Result based on the sq_mobile_profile_get_by_id sproc.
public ProfileDetailsByID_Result GetAllProfileDetailsByID(int profileID)
{
using (IDbConnection connection = OpenConnection("DatabaseConnectionString"))
{
try
{
var profile = connection.Query<ProfileDetailsByID_Result>("sq_mobile_profile_get_by_id",
new { profileid = profileID },
commandType: CommandType.StoredProcedure).FirstOrDefault();
return profile;
}
catch (Exception ex)
{
ErrorLogging.Instance.Fatal(ex); // use singleton for logging
return null;
}
}
}
So using Dapper along with some EDMX entities seems to be a nice quick way to get things going. I may be mistaken, but I'm not sure why Microsoft didn't think this all the way through - no support for complex types with OData.
--- UPDATE ---
So I finally got a response from Microsoft, when I raised the issue over a month ago:
We have done research on this and we have found that the Odata client
library doesn’t support complex types. Therefore, I regret to inform
you that there is not much that we can do to solve it.
*Optional: In order to obtain a solution for this issue, you have to use a Xml to Linq kind of approach to get the complex types.
Thank you very much for your understanding in this matter. Please let
me know if you have any questions. If we can be of any further
assistance, please let us know.
Best regards,
Seems odd.