I am using hibernate version: 4.3.8.Final
In web.xml i have:
`
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.validator.apply_to_ddl" value="true" />
<property name="hibernate.connection.CharSet" value="utf8" />
<property name="hibernate.connection.characterEncoding" value="utf8" />
<property name="hibernate.connection.useUnicode" value="true" />
<property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="300"/>`
When I run app, hibernate generate all table in: latin1_swedish_ci
I read a lot of pages on google, but nothing help me.
How can I generate utf8 table using hibernate? IT IS POSSIBLE?
Thank you for any help.
If you check the org.hibernate.dialect.MySQL5InnoDBDialect implementation you'll find this :
package org.hibernate.dialect;
/**
* #author Gavin King, Scott Marlow
*/
public class MySQL5InnoDBDialect extends MySQL5Dialect {
public boolean supportsCascadeDelete() {
return true;
}
public String getTableTypeString() {
return " ENGINE=InnoDB";
}
public boolean hasSelfReferentialForeignKeyBug() {
return true;
}
}
So you can see in getTableTypeString the return value, what you can do is extends the MySQLDialect class and override getTableTypeString method to return
"ENGINE=InnoDB DEFAULT CHARSET=utf8";
Otherwise (you can try a lazy solution) try with adding UseUnicode=true&characterEncoding=utf8 at the end of your database connection url
Related
I'm new with serverless framework. I'm trying to make a test of a simple application with maven, spring, hibernate, jpa, mysql and serverless.
this is my project
As a restApi works ok, but when I invoke the function in serverless terminal the information came null, because is not getting the info from the db.
this is my code
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="serverless-java" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.serverless.persistence.Wizard</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://mydb.uiyfuas7434.us-east-1.rds.amazonaws.com:3306/mydb" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="1234" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<!-- Important -->
<property name="hibernate.connection.provider_class" value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" />
<property name="hibernate.c3p0.max_size" value="10" />
<property name="hibernate.c3p0.min_size" value="0" />
<property name="hibernate.c3p0.acquire_increment" value="1" />
<property name="hibernate.c3p0.idle_test_period" value="120" />
<property name="hibernate.c3p0.max_statements" value="0" />
<property name="hibernate.c3p0.timeout" value="240" />
<!-- Features -->
<property name="hibernate.connection.autoReconnect" value = "true"/>
<property name="hibernate.show_sql" value = "false" />
<property name="hibernate.connection.autoReconnectForPools" value = "true"/>
<property name="hibernate.connection.is-connection-validation-required" value = "true"/>
</properties>
</persistence-unit>
</persistence>
my Handler class
public class Handler implements RequestHandler<Map<String, Object>, ApiGatewayResponse> {
private static final Logger logger = LoggerFactory.getLogger(TestService.class);
#Autowired
private IBaseService service;
#Override
public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context) {
List<Wizard> prueba = service.getWizards();
Map<String, Wizard> response = new HashMap<>();
Response responseBody = new Response("success", response);
try {
for (Wizard entity : prueba) {
response.put(entity.getName(), entity);
}
responseBody.setInput(response);
} catch (Exception e) {
logger.error(e.getMessage(), e);
responseBody.setMessage("Fail: " + e.getMessage());
}
return ApiGatewayResponse.builder().setStatusCode(200).setObjectBody(responseBody)
.setHeaders(Collections.singletonMap("This is a test", "AWS Lambda & serverless")).build();
}
}
my serverless.yml
service: aws-java-maven # NOTE: update this with your service name
provider:
name: aws
runtime: java8
iamRoleStatements:
- Effect: "Allow"
Action:
- "mysql:*"
Resource: "*"
package:
artifact: target/hello-dev.jar
functions:
get-transactions:
handler: com.serverless.Handler
I'm getting four 'no setter found for property 'xxxx' in class com.rusapp.batch.trans.OLFMWriter'. A fifth bean in that class does not have an error, inputQueue. The rest have errors in the xml below at each of the property lines.
The beans appear as such:
<bean id="inputQueue" class="com.rusapp.batch.trans.OLFMWriter">
<property name="inputQueue" value="${${ENV}_MQ_FM_INPUT_QUEUE}" />
</bean>
<bean id="replyQueue" class="com.rusapp.batch.trans.OLFMWriter">
<property name="replyQueue" value="${${ENV}_MQ_FM_REPLY_QUEUE}" />
</bean>
<bean id="mqConnectionFactory" class="com.rusapp.batch.trans.OLFMWriter">
<property name="mqConnectionFactory" ref="mqConnection" />
</bean>
<bean id="JMSDestination"
class="com.rusapp.batch.trans.OLFMWriter">
<property name="JMSDestination" ref="jmsDestinationResolver" />
</bean>
<bean id="JMSReplyTo"
class="com.rusapp.batch.trans.OLFMWriter">
<property name="JMSReplyTo" ref="jmsDestinationResolverReceiver" />
</bean>
The setters in the class appear as follows:
public static void setMqConnectionFactory(MQConnectionFactory _mqConnectionFactory) {
OLFMWriter._mqConnectionFactory = _mqConnectionFactory;
}
public static void setReplyQueue(String _replyQueue) {
OLFMWriter._replyQueue = _replyQueue;
}
public static void setJMSDestination(Destination _JMSDestination) {
OLFMWriter._JMSDestination = _JMSDestination;
}
public static void setJMSReplyTo(Destination _JMSReplyTo) {
OLFMWriter._JMSReplyTo = _JMSReplyTo;
}
public void setInputQueue(String inputQueue){
_inputQueue = inputQueue;
}
This is not my code and I'm not too knowledgeable with Spring yet but I can't find anything wrong with the setter names. I thought it was a workspace error but they have persisted through several restarts of Eclipse.
Can anyone find any obvious faults with this code?
Your setters are static which means that they don't conform to the java beans specification.
I think you'll want to use a MethodInvokingFactorybean instead.
<bean abstract="true" id="abstractParent" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="com.rusapp.batch.trans.OLFMWriter"/>
</bean>
<bean id="inputQueue" parent="abstractParent">
<property name="staticMethod" value="setInputQueue" />
<property name="arguments">
<list><value>${${ENV}_MQ_FM_INPUT_QUEUE}</value></list>
</property>
</bean>
<bean id="replyQueue" parent="abstractParent">
<property name="staticMethod" value="setReplyQueue" />
<property name="arguments">
<list><value>${${ENV}_MQ_FM_REPLY_QUEUE}</value></list>
</property>
</bean>
etc...
I have this situation:
class User
#Entity
#Configurable(preConstruction=true)
public class User extends AbstractBussinessObject implements Serializable {
#OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Warrior> warriors;
...
class UserDto
public class UserDto extends AbstractDto implements Serializable{
private List<WarriorDto> warriors;
private String name;
private String password;
public UserDto() {}
public UserDto(Long id, List<WarriorDto> warriors, String name, String password) {
this.warriors = warriors;
...
class Warrior
#Entity
public class Warrior extends AbstractBussinessObject implements Serializable{
#JoinColumn(name = "user_id")
#ManyToOne
private User user;
...
class WarriorDto
public class WarriorDto extends AbstractDto implements Serializable{
private User user;
...
method in WarriorServiceImpl
#Transactional(readOnly = true)
public List<WarriorDto> getAllWarriors() {
List<Warrior> wars = null;
List<WarriorDto> warsDto = new ArrayList<WarriorDto>();
try {
wars = genericDao.getAll(Warrior.class);
if (wars != null) {
for (Warrior war : wars) {
warsDto.add(createWarriorDto(war));
}
}
} catch (Exception e) {}
return warsDto;
}
method in DAO
#SuppressWarnings("unchecked")
#Override
public <ENTITY> List<ENTITY> getAll(Class<ENTITY> clazz) {
return getEntityManager().createQuery(
"SELECT e FROM " + clazz.getSimpleName() + " e")
.getResultList();
}
applicationContext.xml
<!-- Connection pool -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="2" />
<property name="minIdle" value="2" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${jpa.platform}" />
<property name="generateDdl" value="true" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="packagesToScan" value="cz.sutak.game" />
</bean>
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Podpora deklarativni demarkace transakci - anotace #Transactional -->
<tx:annotation-driven transaction-manager="txManager" mode="aspectj" />
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="txManager" />
</property>
</bean>
complete code
https://github.com/sutakjakub/game
And if I want call WarriorService.Util.getInstance().getAllWarriors(
new AsyncCallback<List<WarriorDto>>() in widgets it will failure with this message: com.google.gwt.user.client.rpc.StatusCodeException: 500 The call failed on the server; see server log for details.
In Jetty is only this message: [ERROR] 500 - POST /game/warrior (127.0.0.1) 57 bytes
No error message more.
Is problem in serialization (util.List)? Do u have some idea?
Thank you very much.
EDIT:
This is error message in terminal (sorry i didnt look that):
ERROR LazyInitializationException - failed to lazily initialize a collection of role: cz.sutak.game.client.bo.User.warriors, no session or session was closed
The problem is that on the client side Hibernate has no way of fetching the attributes you marked with fetch = FetchType.LAZY. You either need to fetch them eagerly on the server side og null the Hibernate proxies before passing the object graph over the wire.
See my answer in another thread for tips on nulling Hibernate proxies.
Cheers,
Here As you said there is nothing to do with GWT,because its server side code.Even on clien side GWT supports Util.List.
And coming to the original problem.Its with the line wars = genericDao.getAll(Warrior.class);
while accessing this line there is no hibernate session opened.
I have a default database and sometimes I have to make a select in another database.
I've searched many blogs and questions here about this, but couldn't make it work.
Tried the http://blog.springsource.org/2007/01/23/dynamic-datasource-routing/ way. Nothing.
Code for RouterDataSource class:
public class RouterDataSource extends AbstractRoutingDataSource {
#Override
protected DataSourceEnum determineCurrentLookupKey() {
return DataSourceContextHolder.getTargetDataSource();
}
}
Code for DataSourceContextHolder class:
public class DataSourceContextHolder {
private static final ThreadLocal<DataSourceEnum> contextHolder = new ThreadLocal<DataSourceEnum>();
public static void setTargetDataSource(DataSourceEnum targetDataSource) {
Assert.notNull(targetDataSource, "Target data source cannot be null");
contextHolder.set(targetDataSource);
}
public static DataSourceEnum getTargetDataSource() {
if (contextHolder.get() != null)
return (DataSourceEnum) contextHolder.get();
else
return DataSourceEnum.DB1;
}
public static void resetDefaultDataSource() {
contextHolder.remove();
}
}
Code for the method calling to change the database:
#Override
public CodeHD getCategoryByCode(String code) throws BusinessException {
DataSourceContextHolder.setTargetDataSource(DataSourceEnum.DATABASE2);
return (CodeHD) persistency.getObject(GETOBJECT_BY_CODE, code);
}
Code for DatasourceEnum class:
public enum DataSourceEnum {
DB1,
DB2;
}
And finally the configuration on my applicationContext.xml:
<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" abstract="true">
<property name="driverClass" value="oracle.jdbc.pool.OracleDataSource" />
<property name="acquireIncrement" value="10" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="maxStatements" value="50" />
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="15" />
</bean>
<bean id="database1DS" parent="parentDataSource">
<property name="jdbcUrl" value="jdbc:oracle:thin:#database1:1521:xe" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>
<bean id="database2DS" parent="parentDataSource">
<property name="jdbcUrl" value="jdbc:oracle:thin:#database2:1521:xe" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" class="package.RouterDataSource">
<property name="defaultTargetDataSource" ref="database1DS"/>
<property name="targetDataSources">
<map key-type="package.DataSourceEnum">
<entry key="DB1" value-ref="database1DS"/>
<entry key="DB2" value-ref="database2DS"/>
</map>
</property>
</bean>
The problem is that when I set it to DB2 it won't change.
Can anyone help me?
Try to make both static method as non static and pass R reference if the context holder.
First make sure that database2DS is working correctly. Make the defaultTargetDatasource database2DS and verify that it is not using DB1 still and there are no other errors using database2DS as the default. If the AbstractRoutingDataSource fails to resolve a DataSource in the targetDataSources you cannot switch to it.
AbstractRoutingDataSource will only change the DataSource when getConnection is called. Whatever persistence framework you're using is probably caching the Connection and not calling getConnection in between persistency.getObject(). However you are getting your persistency object, try getting a new persistency object after you change the datasource in DataSourceContextHolder. If this solves your problem, try creating a class that maintains your persistency object and handles changing the datasource. That way when you change the datasource you can modify your persistency manager object in one spot.
Ok I have a resource in Tomcat 5.5 in server.xml for database connection like this:
<Resource name="jdbc/MyApp" auth="Container" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" maxPoolSize="100" minPoolSize="5"
acquireIncrement="5"
user="username"
password="password"
factory="org.apache.naming.factory.BeanFactory"
jdbcUrl="jdbc:sqlserver://localhost:1433;databaseName=myDatabase;autoReconnect=true" />
Has anyone tried to extend the above ComboPooledDataSource? Problem is that database password is in clear text. Idea is to first encrypt the password and place the encrypted key in the server.xml. I have a decrypting utility so I can decrypt the key before trying to connect to database.
I found an example solution for my problem for org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory, but I'm not using this connection pool. I'm using C3P0. Anyone tried this before with C3P0?
Yes, you can't extend com.mchange.v2.c3p0.ComboPooledDataSource because it is public. Here is the workaround by which I have achieved this.
I have extended org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy and passed the com.mchange.v2.c3p0.ComboPooledDataSource datasource as a constructor argument.
Here is my hibernate.cfg.xml configuration of above datasource:
<bean id="dataSource" class="MyDataSource">
<constructor-arg ref="c3p0DataSource" />
</bean>
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driver.className}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="acquireIncrement" value="${dataSource.acquireIncrement}" />
<property name="acquireRetryAttempts" value="${dataSource.acquireRetryAttempts}" />
<property name="acquireRetryDelay" value="${dataSource.acquireRetryDelay}" />
<property name="autoCommitOnClose" value="${dataSource.autoCommitOnClose}" />
<property name="breakAfterAcquireFailure" value="${dataSource.breakAfterAcquireFailure}" />
<property name="checkoutTimeout" value="${dataSource.checkoutTimeout}" />
<property name="debugUnreturnedConnectionStackTraces"
value="${dataSource.debugUnreturnedConnectionStackTraces}" />
<property name="forceIgnoreUnresolvedTransactions"
value="${dataSource.forceIgnoreUnresolvedTransactions}" />
<property name="idleConnectionTestPeriod" value="${dataSource.idleConnectionTestPeriod}" />
<property name="initialPoolSize" value="${dataSource.initialPoolSize}" />
<property name="maxAdministrativeTaskTime" value="${dataSource.maxAdministrativeTaskTime}" />
<property name="maxConnectionAge" value="${dataSource.maxConnectionAge}" />
<property name="maxIdleTime" value="${dataSource.maxIdleTime}" />
<property name="maxIdleTimeExcessConnections" value="${dataSource.maxIdleTimeExcessConnections}" />
<property name="maxPoolSize" value="${dataSource.maxPoolSize}" />
<property name="maxStatements" value="${dataSource.maxStatements}" />
<property name="maxStatementsPerConnection" value="${dataSource.maxStatementsPerConnection}" />
<property name="minPoolSize" value="${dataSource.minPoolSize}" />
<property name="numHelperThreads" value="${dataSource.numHelperThreads}" />
<property name="propertyCycle" value="${dataSource.propertyCycle}" />
<property name="testConnectionOnCheckin" value="${dataSource.testConnectionOnCheckin}" />
<property name="testConnectionOnCheckout" value="${dataSource.testConnectionOnCheckout}" />
<property name="unreturnedConnectionTimeout" value="${dataSource.unreturnedConnectionTimeout}" />
</bean>
Mine jdbc.properties file:
jdbc.driver.className=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=xxxxx
jdbc.username=xxx
jdbc.password=xxxxxxxxx #Encrytped password here
jdbc.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.show_sql=false
hibernate.hbm2ddl.auto=update
dataSource.acquireIncrement=3
dataSource.acquireRetryAttempts=30
dataSource.acquireRetryDelay=60000
dataSource.autoCommitOnClose=false
dataSource.breakAfterAcquireFailure=false
dataSource.checkoutTimeout=0
dataSource.debugUnreturnedConnectionStackTraces=false
dataSource.forceIgnoreUnresolvedTransactions=false
dataSource.idleConnectionTestPeriod=0
dataSource.initialPoolSize=10
dataSource.maxAdministrativeTaskTime=0
dataSource.maxConnectionAge=0
dataSource.maxIdleTime=0
dataSource.maxIdleTimeExcessConnections=0
dataSource.maxPoolSize=10
dataSource.maxStatements=0
dataSource.maxStatementsPerConnection=0
dataSource.minPoolSize=10
dataSource.numHelperThreads=3
dataSource.propertyCycle=0
dataSource.testConnectionOnCheckin=false
dataSource.testConnectionOnCheckout=false
dataSource.unreturnedConnectionTimeout=0
Mine extended class where I decrypt the password before passing the datasource to transaction Proxy wrapper.
import javax.sql.DataSource;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import com.csc.emms.common.EMMSConstraints;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class MyDataSource extends TransactionAwareDataSourceProxy
{
private static char[] appName =
{
'B', 'I', 'N', 'G', 'O', 'D', 'I', 'N', 'G', 'O'
};
#Autowired
// Inject your class by constructor
MyDataSource(ComboPooledDataSource dataSource)
{
super.setTargetDataSource(decryptPassword(dataSource));
}
private DataSource decryptPassword(ComboPooledDataSource dataSource)
{
dataSource.setPassword(decode(dataSource.getPassword()));
return dataSource;
}
private String decode(String encodedPassword)
{
BasicTextEncryptor decoder = new BasicTextEncryptor();
decoder.setPasswordCharArray(appName);
return decoder.decrypt(encodedPassword);
}
private String encode(String password)
{
BasicTextEncryptor encoder = new BasicTextEncryptor();
encoder.setPasswordCharArray(appName);
return encoder.encrypt(password);
}
}
Hope this resolved your issue.
You can't extend ComboPooledDataSource, but you can basically duplicate it by extending its parent class, AbstractComboPooledDataSource. You can really, really get close to duplicating it by either getting the source from Github, or by decompiling the class file. The result will look something like this:
import com.mchange.v2.c3p0.AbstractComboPooledDataSource;
public final class YourC3p0DataSource extends AbstractComboPooledDataSource
implements Serializable, Referenceable {
public void setPassword(String encryptedPassword) {
try {
String decryptedPassword
= yourDecryption(encryptedPassword);
super.setPassword(decryptedPassword);
} catch (Exception e) { /* ... */ }
}
/* Increment a few other methods found in ComboPooledDataSource. */
}
you can using jasypt to encrypt properties file and then used encrypted properties in datasource bean.
jasypt also support spring and it is very easy to use.
read this for more details.
Since com.mchange.v2.c3p0.ComboPooledDataSource is
public final class, you can't extend it.