I've got a custom entity in MS Dynamics CRM 4 (old, yes I know, we're planning on migrating to newer soon). I've got the "main application form" showing some of the custom attributes that are on the entity. When a new record is created for this entity there are some attributes that don't get saved (some lookups to related entities, and a decimal field attribute). These attributes are not read-only, there is no client-side scripting, and no workflows to prevent saving the attributes. The user I'm testing with has full "System Administrator" permission with access to all custom entities, so it shouldn't be a permission issue. I've turned on verbose trace logging for CRM, and it appears that the CRM engine is being told to save the attributes:
>InProcessCrmService starts processing request for user:CreateRequest
As user:xxxxxxxx-e990-dd11-870d-005056c00008
Request Xml:
<?xml version="1.0" encoding="utf-16"?>
<CreateRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/crm/2007/WebServices">
<OptionalParameters>
<OptionalParameter xsi:type="CreateDuplicatesOptionalParameter">
<Value>false</Value>
</OptionalParameter>
</OptionalParameters>
<Target xsi:type="TargetCreateDynamic">
<Entity Name="new_job">
<Properties xmlns="http://schemas.microsoft.com/crm/2006/WebServices">
<Property xsi:type="OwnerProperty" Name="ownerid">
<Value name="Joe Blow Admin" type="systemuser">xxxxxxxx-aa8f-e111-8548-005056c00008</Value>
</Property>
<Property xsi:type="LookupProperty" Name="new_accountid">
<Value name="A Walk In Client" type="account">xxxxxxx-22cd-dd11-9db5-005056c00008</Value>
</Property>
<Property xsi:type="PicklistProperty" Name="new_childcompany">
<Value name="Road Pavers Inc">4</Value>
</Property>
<Property xsi:type="CrmDateTimeProperty" Name="new_startdate">
<Value>2016-06-12T00:00:00</Value>
</Property>
<Property xsi:type="CrmDateTimeProperty" Name="new_enddate">
<Value>2016-06-15T00:00:00</Value>
</Property>
<Property xsi:type="CrmBooleanProperty" Name="new_productionjob">
<Value>false</Value>
</Property>
<Property xsi:type="CrmBooleanProperty" Name="new_billed">
<Value>false</Value>
</Property>
<Property xsi:type="LookupProperty" Name="new_revenuecityid">
<Value name="Toronto" type="new_citylocation">xxxxxxxx-6eda-e511-aa42-0050569e01ef</Value>
</Property>
<Property xsi:type="LookupProperty" Name="new_industrycodeid">
<Value name="Other" type="new_industrycode">xxxxxxxx-6eda-e511-aa42-0050569e01ef</Value>
</Property>
<Property xsi:type="LookupProperty" Name="new_jobconfidencelevelid">
<Value name="Low" type="new_jobconfidence">xxxxxxxx-1124-e611-aa44-0050569e01ef</Value>
</Property>
<Property xsi:type="CrmDecimalProperty" Name="new_estimatedhoursperday">
<Value>5.3</Value>
</Property>
<Property xsi:type="StringProperty" Name="new_description">
<Value>Testing job creation</Value>
</Property>
<Property xsi:type="PicklistProperty" Name="new_avgweight">
<Value name="Heavy">1</Value>
</Property>
<Property xsi:type="LookupProperty" Name="transactioncurrencyid">
<Value name="Canadian Dollar" type="transactioncurrency">a0599012-25f2-dc11-9dc3-00c09f3657d9</Value>
</Property>
<Property xsi:type="StateProperty" Name="statecode">
<Value>Active</Value>
</Property>
</Properties>
</Entity>
</Target>
</CreateRequest>
I've also used SQL server profiling to see what actually gets sent to SQL:
exec sp_executesql
N'insert into New_JobBase(
ExchangeRate,
OwningBusinessUnit,
New_JobId,
CreatedOn,
StateCode,
StatusCode,
OwningUser,
ModifiedBy,
CreatedBy,
DeletionStateCode,
ModifiedOn,
TransactionCurrencyId)
values (
#ExchangeRate0,
#OwningBusinessUnit0,
#New_JobId0,
#CreatedOn0,
#StateCode0,
#StatusCode0,
#OwningUser0,
#ModifiedBy0,
#CreatedBy0,
#DeletionStateCode0,
#ModifiedOn0,
#TransactionCurrencyId0);
insert into New_JobExtensionBase(
new_accountid,
New_EndDate,
New_JobId,
New_Description,
New_ChildCompany,
New_Billed,
New_StartDate,
New_avgweight,
New_ProductionJob)
values (
#new_accountid0,
#New_EndDate0,
#New_JobId1,
#New_Description0,
#New_ChildCompany0,
#New_Billed0,
#New_StartDate0,
#New_avgweight0,
#New_ProductionJob0)',
N'#ExchangeRate0 decimal(11,10),
#OwningBusinessUnit0 uniqueidentifier,
#New_JobId0 uniqueidentifier,
#CreatedOn0 datetime,
#StateCode0 int,
#StatusCode0 int,
#OwningUser0 uniqueidentifier,
#ModifiedBy0 uniqueidentifier,
#CreatedBy0 uniqueidentifier,
#DeletionStateCode0 int,
#ModifiedOn0 datetime,
#TransactionCurrencyId0 uniqueidentifier,
#new_accountid0 uniqueidentifier,
#New_EndDate0 datetime,
#New_JobId1 uniqueidentifier,
#New_Description0 ntext,
#New_ChildCompany0 int,
#New_Billed0 bit,
#New_StartDate0 datetime,
#New_avgweight0 int,
#New_ProductionJob0 bit
',
#ExchangeRate0=1.0000000000,
#OwningBusinessUnit0='xxxxxxxx-E990-DD11-870D-005056C00008',
#New_JobId0='xxxxxxxx-0838-E611-AA44-0050569E01EF',
#CreatedOn0='Jun 21 2016 11:35:22:000PM',
#StateCode0=0,
#StatusCode0=1,
#OwningUser0='xxxxxxxx-AA8F-E111-8548-005056C00008',
#ModifiedBy0='xxxxxxxx-AA8F-E111-8548-005056C00008',
#CreatedBy0='xxxxxxxx-AA8F-E111-8548-005056C00008',
#DeletionStateCode0=0,
#ModifiedOn0='Jun 21 2016 11:35:22:000PM',
#TransactionCurrencyId0='A0599012-25F2-DC11-9DC3-00C09F3657D9',
#new_accountid0='xxxxxxxx-22CD-DD11-9DB5-005056C00008',
#New_EndDate0='Jun 15 2016 6:00:00:000AM',
#New_JobId1='xxxxxxxx-0838-E611-AA44-0050569E01EF',
#New_Description0=N'Testing job creation',
#New_ChildCompany0=4,
#New_Billed0=0,
#New_StartDate0='Jun 12 2016 6:00:00:000AM',
#New_avgweight0=1,
#New_ProductionJob0=0
As you can see above, some attributes, like new_avgweight, new_description, or a lookup like the new_accountid are being created properly. Other attributes, like new_industrycode or new_estimatedhoursperday are not being passed along to SQL.
Once the record has been created, it is possible to open it up, enter the data and it will save correctly. It is only failing to save when it is a new record first being created.
Why does it seem like CRM is saving some atttributes, but not other attributes? I've tried deleting an attribute and adding it back to the entity to see if that would force CRM to re-generate it, but to no avail.
We have an application that works in an EC2 cluster (2 nodes currently for testing). For searching domain models we use Hibernate Search, and since the application runs on a cluster we use Infinispan as the Lucene Directory. To survive restarts we use a JDBC cache store on MySQL, both nodes accessing the same MySQL tables. To account for adding and removing nodes, we use the "jgroups" backend for Hibernate Search worker configuration.
Our problem is about duplicate records exceptions we receive when we try to rebuild the whole entity index. We get errors with similar stacktraces as this:
ERROR [AsyncStoreProcessor-LuceneIndexesData-0] [2016-06-21 17:01:59] org.infinispan.persistence.jdbc.stringbased.JdbcStringBasedStore - ISPN008024: Error while storing string key to database; key: '_d.fdt|0|1048576|com.model.SomeModel'
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '_d.fdt|0|1048576|com.model.SomeModel' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1399)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:857)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
at com.zaxxer.hikari.proxy.PreparedStatementJavassistProxy.executeUpdate(PreparedStatementJavassistProxy.java)
at org.infinispan.persistence.jdbc.stringbased.JdbcStringBasedStore.write(JdbcStringBasedStore.java:174)
at org.infinispan.persistence.async.AsyncCacheWriter.applyModificationsSync(AsyncCacheWriter.java:158)
at org.infinispan.persistence.async.AsyncCacheWriter$AsyncStoreProcessor.retryWork(AsyncCacheWriter.java:330)
at org.infinispan.persistence.async.AsyncCacheWriter$AsyncStoreProcessor.run(AsyncCacheWriter.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
When we check the DB, there is an entry with this ID. When we try it with a single node there are no errors. So our guess is both nodes are trying to write the cache entry to DB. What may be causing this problem? AFAIK the jgroups backend should be preventing it.
We use hibernate 4.3.9.Final, hibernate-search 5.2.1.Final, infinispan 7.2.5.Final and jgroups 3.6.8.Final. Infinispan configuration is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:7.2"
xmlns:jdbc="urn:infinispan:config:store:jdbc:7.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
urn:infinispan:config:7.2 http://www.infinispan.org/schemas/infinispan-config-7.2.xsd
urn:infinispan:config:store:jdbc:7.2 http://www.infinispan.org/schemas/infinispan-cachestore-jdbc-config-7.2.xsd">
<jgroups>
<stack-file name="tcp" path="default-configs/default-jgroups-tcp.xml"/>
<stack-file name="ec2" path="search/infinispan-jgroups-ec2.xml"/>
</jgroups>
<cache-container name="HibernateSearch" default-cache="default" statistics="false" shutdown-hook="DONT_REGISTER">
<transport stack="${infinispan.transport:tcp}"/>
<!-- Duplicate domains are allowed so that multiple deployments with default configuration
of Hibernate Search applications work - if possible it would be better to use JNDI to share
the CacheManager across applications -->
<jmx duplicate-domains="true"/>
<!-- *************************************** -->
<!-- Cache to store Lucene's file metadata -->
<!-- *************************************** -->
<replicated-cache name="LuceneIndexesMetadata" mode="SYNC" remote-timeout="25000">
<transaction mode="NONE"/>
<state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
<indexing index="NONE"/>
<locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
<eviction max-entries="-1" strategy="NONE"/>
<expiration max-idle="-1"/>
<persistence passivation="false">
<jdbc:string-keyed-jdbc-store preload="true" fetch-state="true" read-only="false" purge="false">
<jdbc:data-source jndi-url="java:comp/env/jdbc/..."/>
<jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ISPN_STRING_TABLE">
<jdbc:id-column name="ID" type="VARCHAR(255)"/>
<jdbc:data-column name="METADATA" type="BLOB"/>
<jdbc:timestamp-column name="TIMESTAMP" type="BIGINT"/>
</jdbc:string-keyed-table>
<property name="key2StringMapper">org.infinispan.lucene.LuceneKey2StringMapper</property>
<write-behind/>
</jdbc:string-keyed-jdbc-store>
</persistence>
</replicated-cache>
<!-- **************************** -->
<!-- Cache to store Lucene data -->
<!-- **************************** -->
<distributed-cache name="LuceneIndexesData" mode="SYNC" remote-timeout="25000">
<transaction mode="NONE"/>
<state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
<indexing index="NONE"/>
<locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
<eviction max-entries="-1" strategy="NONE"/>
<expiration max-idle="-1"/>
<persistence passivation="false">
<jdbc:string-keyed-jdbc-store preload="true" fetch-state="true" read-only="false" purge="false">
<jdbc:data-source jndi-url="java:comp/env/jdbc/..."/>
<jdbc:string-keyed-table drop-on-exit="false" create-on-start="true" prefix="ISPN_STRING_TABLE">
<jdbc:id-column name="ID" type="VARCHAR(255)"/>
<jdbc:data-column name="DATA" type="MEDIUMBLOB"/>
<jdbc:timestamp-column name="TIMESTAMP" type="BIGINT"/>
</jdbc:string-keyed-table>
<property name="key2StringMapper">org.infinispan.lucene.LuceneKey2StringMapper</property>
<write-behind/>
</jdbc:string-keyed-jdbc-store>
</persistence>
</distributed-cache>
<!-- ***************************** -->
<!-- Cache to store Lucene locks -->
<!-- ***************************** -->
<replicated-cache name="LuceneIndexesLocking" mode="SYNC" remote-timeout="25000">
<transaction mode="NONE"/>
<state-transfer enabled="true" timeout="480000" await-initial-transfer="true"/>
<indexing index="NONE"/>
<locking striping="false" acquire-timeout="10000" concurrency-level="500" write-skew="false"/>
<eviction max-entries="-1" strategy="NONE"/>
<expiration max-idle="-1"/>
</replicated-cache>
</cache-container>
</infinispan>
Respective Hibernate configuration is as follows (which is done via Spring):
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="..."/>
<property name="packagesToScan" value="com...."/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false"/>
<property name="showSql" value="false"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="database" value="MYSQL"/>
</bean>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.default_batch_fetch_size" value="50"/>
<entry key="hibernate.multiTenancy" value="SCHEMA"/>
<entry key="hibernate.multi_tenant_connection_provider" value-ref="connectionProvider"/>
<entry key="hibernate.tenant_identifier_resolver" value-ref="tenantIdentifierResolver"/>
<entry key="hibernate.cache.use_second_level_cache" value="true"/>
<entry key="hibernate.cache.region.factory_class" value="com.hazelcast.hibernate.HazelcastCacheRegionFactory"/>
<entry key="hibernate.cache.hazelcast.use_native_client" value="true"/>
<entry key="hibernate.cache.hazelcast.native_client_address" value="127.0.0.1"/>
<entry key="hibernate.cache.hazelcast.native_client_group" value="dev"/>
<entry key="hibernate.cache.hazelcast.native_client_password" value="dev-pass"/>
<entry key="hibernate.connection.characterEncoding" value="UTF-8"/>
<entry key="hibernate.connection.useUnicode" value="true"/>
<entry key="hibernate.search.default.directory_provider" value="infinispan"/>
<entry key="hibernate.search.default.locking_cachename" value="LuceneIndexesLocking"/>
<entry key="hibernate.search.default.data_cachename" value="LuceneIndexesData"/>
<entry key="hibernate.search.default.metadata_cachename" value="LuceneIndexesMetadata"/>
<entry key="hibernate.search.default.chunk_size" value="1048576"/>
<entry key="hibernate.search.infinispan.configuration_resourcename" value="search/hibernatesearch-infinispan.xml"/>
<entry key="hibernate.search.default.worker.backend" value="jgroups"/>
<entry key="hibernate.search.services.jgroups.configurationFile" value="search/infinispan-jgroups-ec2.xml"/>
</map>
</property>
</bean>
You are correct on the purpose of the JGroups Backend and your configuration of Hibernate looks like correct.
The problem is on the configuration of the CacheStore component in Infinispan, these have a "shared" attribute, whose default is false.
<jdbc:string-keyed-jdbc-store
preload="true"
fetch-state="true"
read-only="false"
purge="false"
shared="true" <!-- FIX
As you suspected, each Infinispan node was going to re-write the same entry on "each" CacheStore instance, as it didn't guess that each of your nodes are actually connecting to the same database.
Setting the shared attribute to true should ensure that Infinispan's core will coordinate among nodes so that one (and only one) node will write the entry.
I used CAS server 4.0 and cas-overlay-server-demo. the return value of my server is as following:
<cas:serviceResponse xmlns:cas="xxx">
<cas:authenticationSuccess>
<cas:user>try</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
I want to add <cas:attributes> to this return result. I have following code in deployerConfigContext.xml:
primaryAuthenticationHandler:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<entry key="test" value="1234"/>
</map>
</property>
</bean>
primaryPrincipalResolver:
<bean id="primaryPrincipalResolver"
class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver" >
<property name="attributeRepository" ref="attributeRepository" />
</bean>
attributeRepository:
<bean id="attributeRepository" class="org.jasig.services.persondir.support.StubPersonAttributeDao"
p:backingMap-ref="attrRepoBackingMap" />
<util:map id="attrRepoBackingMap">
<entry key="uid" value="uid" />
<entry key="prénom" value="eduPersonAffiliation" />
<entry key="groupMembership" value="groupMembership" />
</util:map>
I think I have add the the code right. StubPersonAttributeDao will help me to add attributes: uid and prénom and groupMembership. BUT, I still do not get any attibutes. Is there anything wrong in the code?
You probably need to authorize your application in CAS service registry to release attributes. By default, nothing is allowed. See http://apereo.github.io/cas/4.0.x/integration/Attribute-Release.html
I am trying to build a simple application using Hibernate JPA with MySQL but I keep getting a "Missing table" error whenever I try to deploy it to Wildfly.
My persistent class looks like this:
package com.example;
#Entity #Table
public class FooBar {
//...
}
Here is my persistence.xml:
<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="ExampleJPA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.example.FooBar</class>
<properties>
<!-- Configuring JDBC properties -->
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mydatabase" />
<property name="javax.persistence.jdbc.user" value="(my user)" />
<property name="javax.persistence.jdbc.password" value="(my password)" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<!-- Hibernate properties -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="validate" />
<!-- Configuring Connection Pool -->
<property name="hibernate.c3p0.min_size" value="5" />
<property name="hibernate.c3p0.max_size" value="20" />
<property name="hibernate.c3p0.timeout" value="500" />
<property name="hibernate.c3p0.max_statements" value="50" />
<property name="hibernate.c3p0.idle_test_period" value="2000" />
</properties>
</persistence-unit>
</persistence>
And this is the message I get when deploying to a Wildfly 8 server:
org.jboss.msc.service.StartException in service jboss.persistenceunit.\"ExampleJPA.war#ExampleJPA\": org.hibernate.HibernateException: Missing table: FooBar
Caused by: org.hibernate.HibernateException: Missing table: FooBar
I do have a table called FooBar in the database. I can access it directly with JDBC using the same url, user and password defined in the persistence.xml. What is wrong with my JPA setup?
Your table doesn't exist in the schema, so the hibernate.hbm2ddl.auto value of "validate" fails. Either create the table or change the hibernate.hbm2ddl.auto value to "create" or "update".
I have JSF 2.2, Primefaces 3.5, Spring, Spring Security 3.x, Hibernate 4, MySQL web application.
I have enabled Spring Security to work as expected, but I used <user-service/> in which I created two users with different roles ("ROLE_USER", "ROLE_ADMIN"). Now I would like to search for every user in the database, and not to create them manualy in <user-service/>.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- GLOABL SETTINGS -->
<context:component-scan base-package="com.infostroy.adminportal"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- DATA SOURCE AND PERSISTENCE SETTINGS -->
<bean id="propertiesPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dmDataSource"/>
<property name="packagesToScan" value="com.infostroy.adminportal"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.show_sql">${db.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl_auto}</prop>
<prop key="connection.pool_size">${db.pool_size}</prop>
<prop key="current_session_context_class">${db.current_session_context_class}</prop>
<prop key="org.hibernate.FlushMode">${db.flush_mode}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dmDataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxWait" value="5000" />
<property name="initialSize" value="2" />
<property name="maxActive" value="100"/>
<property name="maxIdle" value="50"/>
<property name="minIdle" value="0"/>
</bean>
</beans>
spring-security.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="false" use-expressions="true">
<intercept-url pattern="/protected/*" access="isAuthenticated()"/>
<form-login login-page="/login.xhtml" login-processing-url="/j_spring_security_check"
default-target-url="/protected/home.xhtml"
authentication-failure-url="/loginFailed.xhtml"/>
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="c" password="c" authorities="ROLE_ADMIN" />
<user name="q" password="q" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
Here's the script to create users table:
CREATE TABLE users (
user_id INT AUTO_INCREMENT,
first_name VARCHAR(20),
last_name VARCHAR(20),
login VARCHAR(20) NOT NULL UNIQUE,
password VARCHAR(32) NOT NULL,
role VARCHAR(20) NOT NULL,
PRIMARY KEY(user_id)
) ENGINE=InnoDB;
Does anyone know how to achieve this? Every answer is highly appreciated and responded quickly!
Thank you.
Just change the authentication-manager to :
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dmDataSource"
users-by-username-query="
select login as username,password, 1 as enabled
from users where login=?"
authorities-by-username-query="
select login as username, role as authority from users
where login =? "
/>
</authentication-provider>
</authentication-manager>
I assume the login field is the username. I hardcoded the enable flag, it's rquired. If you add deleteflag or enabled flag in the future you can replace it.