Everyone.
I am working on some Java servlet with JDBC access to PostgreSQL DB. Application is using DataSource defined as resource in server's context. DataSource has auto commit property set to "false" - I am managing transactions from servlet.
In application I have following code:
String query =
"insert into auth_selling_permissions "
+ "(selling_permissions_key, "
+ "sell "
+ ") values ( "
+ " DEFAULT, "
+ PermissionLevel.getIntegerValue(org.getSell())+") "
+ " returning selling_permissions_key";
List<Map<String,Object>> list = this.template.queryForList(query);
Integer outKey = (Integer)list.get(0).get("selling_permissions_key");
Within same transaction I am doing the following action:
for(Map<String,Object> prod : listProducts){
Integer k = (Integer)prod.get("type_key");
keysSection+="("+outKey+", "+k+"),";
}
if(keysSection.length()>0){
keysSection = keysSection.substring(0, keysSection.length()-1);
String bindingQuery = "insert into auth_selling_products_permissions (selling_permissions_key, type_key) values "+keysSection;
this.template.update(bindingQuery);
}
Code above is meant to insert a row to selling_permission table, get back newly generated key and, using it, fill related table (which uses selling_permission_key as FK).
As I mentioned, all is done within single transaction.
The problem is: I am using for developement STS with vFabric tc server. In dev environment it works great. But production env. uses Tomcat 7.0. When I am runnin my servlet on Tomcat 7 (using same database server, same JDBC driver and same definition of db resource) - it fails. It gives me org.springframework.dao.DataIntegrityViolationException and tells that key, which I am trying to insert into auth_selling_products_permissions does not exist in auth_selling_permissions.
I am quite sure that the problem is on server level. But I have now idea why Tomcat behaves like that, and what should I check/configure/change to make it work as my dev tc server.
EDIT:
Resource definition:
<Resource name="jdbc/calc_webapp" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="dbuser" password="password" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/prod_db" defaultAutoCommit = "false"/>
Exactly the same on both servers.
Related
I've got an Azure SQL Server database that I'm connecting to via JDBC, but want to connect instead to my SQL Server "localhost". In SSMS, I connect to localhost without needing a password. So, do I still need to enter a password in Java?
I have a code like this :
String connectionUrl =
"jdbc:sqlserver://etcetc.database.windows.net:1433;"
+ "database=med;"
+ "user=windersan#salemimed;"
+ "password=********;"
+ "encrypt=true;"
+ "trustServerCertificate=false;"
// + "hostNameInCertificate=*.database.windows.net;"
+ "loginTimeout=30;";
How do I change this to connect instead to localhost?
Just replace the etcetc.database.windows.net by localhost and replace the port number 1433 by the number that you are using.
I have used SQLServerDataSource class to make the work easier. You can also create a string URL and set it in the DriverManger.getConnection().
Try with this code :
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setUser("windersan#salemimed");
dataSource.setPassword("********");
dataSource.setServerName("localhost");
// set the port number of your system below.
dataSource.setPortNumber(1433);
dataSource.setDatabaseName("med");
dataSource.setEncrypt(true);
dataSource.setHostNameInCertificate("*.database.windows.net");
dataSource.setTrustServerCertificate(false);
Connection connection = dataSource.getConnection();
Please refer to this links down below for more info.
Microsoft Docs - ISQLServerDataSource Interface - This contains the list of methods that you can use to set the various properties in the datasource.
Microsoft Docs - How to work with the connection - This contains examples of the possible ways to connect to a SQL Server database.
the first line of your concatenated string contains the url etcetc.database.windows.net:1433 this is the location of the database server, and the bit you should change.
Also, it might be worth doing a google search on connecting to SqlServer with JDBC to see if there are any examples out there.
I am trying to implement Apache Tomcat's built-in JDBC connection pool. But I am confused with many things.
There are 2 methods mentioned in official page to initialize connection pool.
One using JNDI lookup and another by java PoolProperty class.
For JNDI lookup, we have to add entry to context.xmlor server.xml and initilize it in the java code. This require database connection details to be hardcoded.
For pool properties, we have to set various connection attributes in PoolProperty class using the datasource object. Does it require instantiating factory? (org.apache.tomcat.jdbc.pool.DataSourceFactory)
Whenever a try using pool properties, I am getting the error:
SEVERE: Unable to create initial connections of pool.
java.sql.SQLException: invalid arguments in call at
oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
I checked and confirmed all properties are correct. This error goes once I use the xml method. Can someone help me the correct way to configure pooling without xml?
This standalone java code gives me error:
PoolProperties p = new PoolProperties();
String dburl="jdbc:oracle:thin:#(DESCRIPTION=(LOAD_BALANCE=on)(ADDRESS=(PROTOCOL=TCP)(HOST=hostname) (PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=shostname2)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=Service)))";
p.setUrl(dburl);
p.setDriverClassName("oracle.jdbc.OracleDriver");
p.setUsername(username);
p.setPassword(pwd);
p.setJmxEnabled(true);
p.setTestWhileIdle(false);
p.setTestOnBorrow(true);
p.setValidationQuery("SELECT 1 from dual");
p.setTestOnReturn(false);
p.setValidationInterval(30000);
p.setTimeBetweenEvictionRunsMillis(30000);
p.setMaxActive(100);
p.setInitialSize(10);
p.setMaxWait(10000);
p.setRemoveAbandonedTimeout(600);
p.setMinEvictableIdleTimeMillis(30000);
p.setMinIdle(10);
p.setLogAbandoned(true);
p.setRemoveAbandoned(true);
p.setJdbcInterceptors(
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+ "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+ "org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer");
p.setLogValidationErrors(true); datasource = new org.apache.tomcat.jdbc.pool.DataSource( );
datasource.setPoolProperties(p);
When I add A global Resource to Server.xml as below,it is working.
Resource auth="Container" description="User database that can be
updated and saved"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
name="jdbc/database" type="javax.sql.DataSource"/>
Please Help me to understand, what's the correct way of implementation.
Background:
We have 4 physical servers (4 IPS), each one running in JBOSS 6 EAP running on port 80.All requests are redirected to any one of these servers via Load balancer.
Now I tried to implement Java cache system for such distributed env so that our properties gets updated in each servers cache.
POC:
For that we did a small POC on our local systems implementing JCS v1.3 lateral caching.
Enabled it in our maven project. The following config is used in .ccf file :
jcs.default=
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
# PRE-DEFINED CACHE REGION
##############################################################
##### AUXILIARY CACHES
# LTCP AUX CACHE
jcs.auxiliary.LTCP=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.LateralTCPCacheFactory
jcs.auxiliary.LTCP.attributes=org.apache.commons.jcs.auxiliary.lateral.socket.tcp.TCPLateralCacheAttributes
#jcs.auxiliary.LTCP.attributes.TcpServers=152.144.219.209:8080
jcs.auxiliary.LTCP.attributes.TcpListenerPort=1118
jcs.auxiliary.LTCP.attributes.UdpDiscoveryAddr=228.5.6.8
jcs.auxiliary.LTCP.attributes.UdpDiscoveryPort=6780
jcs.auxiliary.LTCP.attributes.UdpDiscoveryEnabled=true
jcs.auxiliary.LTCP.attributes.Receive=true
jcs.auxiliary.LTCP.attributes.AllowGet=true
jcs.auxiliary.LTCP.attributes.IssueRemoveOnPut=false
jcs.auxiliary.LTCP.attributes.FilterRemoveByHashCode=false
jcs.auxiliary.LTCP.attributes.SocketTimeoOt=1001
jcs.auxiliary.LTCP.attributes.OpenTimeOut=2002
jcs.auxiliary.LTCP.attributes.ZombieQueueMaxSize=2000
And implementing the getter and setter methods for saving a string attribute in cache and getting it from cache
public void addProp(String propId)
throws PimsAppException {
try {
configMSCache.put(propId, propId);
} catch (CacheException e) {
e.printStackTrace();
}
}
#Override
public String testProp(String propId) throws PimsAppException {
if(configMSCache!=null){
return (String) configMSCache.get(propId);
}else{
return "It dint work";
}
}
The application is deployed fine no error in getting it up.
TEST METHOD:
deployed the project.war in my local server and in a remote server with different IP. Both machines are in same network, so no firewall issue in accessing each others IP.
Have saved a property in my server and get it. (Worked fine)
Tried to get the saved property via my local by the remote machine. (It returns blank response).
Means the distributed cache feature is NOT achieved.
Doubts :
1. Does the auxiliary caches set up properly? I mean the configurations
2. Am I testing it properly or how can I test it in dev environment.
3. As JCS UDP Discovery,lets us support the same config on multiple machines, then why it dint work on remote machine?
4. Or is there any caching mechanism, with good examples and documentation can suffice my application needs(as mentioned in background section).
Thanks in advance.
This reply might be too late. But I will suggest in case, to log the stats on both servers and see. As could be possible that it is propagating the cache but just in the processing time, there is an issue reading it.
For example:
JCSAdminBean admin = new JCSAdminBean();
LinkedList linkedList = admin.buildCacheInfo();
ListIterator iterator = linkedList.listIterator();
while (iterator.hasNext()) {
CacheRegionInfo info = (CacheRegionInfo)iterator.next();
CompositeCache compCache = info.getCache();
System.out.println("Cache Name: " + compCache.getCacheName());
System.out.println("Cache Type: " + compCache.getCacheType());
System.out.println("Cache Misses (not found): " + compCache.getMissCountNotFound());
System.out.println("Cache Misses (expired): " + compCache.getMissCountExpired());
System.out.println("Cache Hits (memory): " + compCache.getHitCountRam());
System.out.println("Cache value: " + compCache.get(propId));
}
Starting to use Neo4j embedded with my JAVA web server. While saving the data the transaction was successful, but not able to visualize the data via browser.
Have tried sample Hello world from tutorial. And installed neo4j community edition, after pointing to DB and navigating to http://localhost:7474/browser/ i don't see any data.
Also, when i stop the application and run Cypher query via Java not getting any data.
Maven dependency used
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>2.3.1</version>
</dependency>
Sample code written
try {
Transaction tx = graphDb.beginTx();
firstNode = graphDb.createNode();
firstNode.setProperty( "message", "Hello, " );
secondNode = graphDb.createNode();
secondNode.setProperty( "message", "World!" );
relationship = firstNode.createRelationshipTo( secondNode, RelTypes.KNOWS );
relationship.setProperty( "message", "brave Neo4j " );
tx.success();
}
DB path for embedded as well as server is same.
I do not know exact root of the issue. But I have checklist, that should be verified.
1) You application and Neo4j server should use same database. When you are creating embdedded database via GraphDatabaseFactory you are specifying database location. Same database location should be specified for Neo4j server in conf/neo4j-server.properties file (org.neo4j.server.database.location option).
2) You should NOT use database simultaneously in server and application. Database can be used only by one Neo4j instance at a time.
3) Use try-with-resource syntax for transactions. It is available in Java7 and later. Example:
try (Transaction tx = db.beginTx()) {
// do stuff
tx.success();
}
In this way transaction will be always closed, in any case (even if exception occurs during execution, or in beginTx()).
4) Ensure that your database is closed in “clean way”. In application it can be done via db.shutdown() method. Server can be stopped via bin/neo4j stop.
I have a issue populating v$session properties in oracle datasource ie after starting tomcat server my application would be using connection , now if I query DB with below query I should get a row from DB, currently I am not getting any row for 1st approach ,but 2nd approach works
select schemaname, osuser, machine, program
from v$session
where program = 'Test';
below are the configuration and tools I am using , any help regaring this is appriciated .
Thanks
1.Tomcate 6.0.35.3
2.Oracle version :Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
3.Spring and JPA
Approach 1:-
server.xml :
<Resource
name="jdbc/oraclepool"
auth="Container"
factory="oracle.ucp.jdbc.PoolDataSourceImpl"
type="oracle.ucp.jdbc.PoolDataSource"
description="main DB"
connectionFactoryClassName="oracle.jdbc.pool.OracleDataSource"
connectionPoolName="UCPPool"
url="${db.url}"
user="${db.username}"
password="${db.password.encrypted}"
initialPoolSize="3"
minPoolSize="1"
maxPoolSize="5"
maxIdleTime="${db.maxIdleTime}"
inactiveConnectionTimeout="${db.inactiveConnectionTimeout}"
abandonedConnectionTimeout="${db.abandonedConnectionTimeout}"
timeToLiveConnectionTimeout="${db.timeToLiveConnectionTimeout}"
maxStatements="${db.maxOpenPreparedStatements}"
timeoutCheckInterval="${db.timeoutCheckInterval}"
connectionWaitTimeout="${db.connectionWaitTimeout}"
sqlForValidateConnection="${db.validationQuery}"
connectionProperties="v$session.program=Test;"
/>
Approach 2 :-
Added below code snippet in java class , it worked .
When I queried the db with below query , I was getting the row .
select schemaname, osuser, machine, program
from v$session
where program = 'Test';
Connection conn=null;
// set connection properties
Properties info = new java.util.Properties();
info.put("v$session.program", "Test");
// connect to database
Context context = new InitialContext();
PoolDataSourceImpl ds = (PoolDataSourceImpl)context.lookup("java:comp/env/jdbc/oraclepool");
((PoolDataSourceImpl)ds).setConnectionProperties(info);
conn = ds.getConnection();
Can anybody tell what is the issue with first approach
Thanks again .