Override persistence.xml property - glassfish

What would be the proper way to override EclipseLink persistence.xml property when running application on Glassfish application server?
We need some properties to be configured in a separate configuration file which would be available to a client.
I didn't find any EclipseLink-specific classes which accept some user properties. I only found Glassfish PersistenceUnitLoader class which could be tweaked in order to achieve that. But this would be an ugly hack :)

You can create your own EntityManager at runtime:
Map map = new HashMap();
map.put("javax.persistence.jdbc.password", "password");
map.put("javax.persistence.jdbc.user", "root");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPU",map);
EntityManager em = emf.createEntityManager(map);
Some eclipselink property names:
<property name="eclipselink.target-database" value="DERBY"/>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="eclipselink.jdbc.url" value="jdbc:derby://localhost:1527/02DB;create=true"/>
<property name="eclipselink.jdbc.user" value="user"/>
<property name="eclipselink.jdbc.password" value="password"/>

Related

Camel file uri using property

I'm trying to use property file for routing from folder :
My property file has some property :
from.file = D:/Develop/resources
and I want to use it in camel context xml as file routing,
I tried:
<camel:route id="Main-Route">
<camel:from uri="file:${from.file}" />
<camel:to uri="seda:fooQueue" />
</camel:route>
But camel throws me exception :
Dynamic expressions with ${ } placeholders is not allowed. Use the fileName option to set the dynamic expression.
How can I do this ?
In Camel, you use {{property}} to inject properties in your routes.
Please read more here http://camel.apache.org/properties.html.
Your example would change to:
<camel:route id="Main-Route">
<camel:from uri="file:{{from.file}}" />
<camel:to uri="seda:fooQueue" />
</camel:route>
You also need to tell Camel where it can find your properties file. From the link above:
Spring XML offers two variations to configure. You can define a spring bean as a PropertiesComponent which resembles the way done in Java DSL. Or you can use the tag.
<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
<property name="location" value="classpath:com/mycompany/myprop.properties"/>
</bean>
Using the tag makes the configuration a bit more fresh such as:
<camelContext ...>
<propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/>
</camelContext>
In file component of apache camel,the starting directory should not contain dynamic expressions. If you want to provide dynamic starting directory also,you can set the whole path into CamelFileName header of file component from properties file with fileComponent defined as <to uri="file://">
the problem with this is that for reading place holder as :
${some-property} for some bean for example :
<bean id="bean" class="">
<property name="field Constructor" value="${some.property}" />
</bean>
I get error.
Solved it by defining also PropertyPlaceholderConfigurer:
<bean id="proprty" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:/D:/Proj/resources/myprop.properties
</value>
</bean>
<bean id="beanId" class="com.viewlinks.eim.properties.MyBean">
<property name="fieldConstructor" value="${some.property}" />
</bean>
<camel:camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<propertyPlaceholder id="properties" location="file:/D:/Proj/resources/myprop.properties"/>
<camel:route id="Main-Route">
<camel:from uri="file:{{from.file}}" />
<camel:to uri="file:{{to.file}}" />
</camel:route>
</camel:camelContext>

Kundera No Entity metadata found for the class

I get an error "No Entity metadata found for the class" using Kundera a similiar
question is here,
No Entity metadata found for the class
but didn't find an answer (answer put META-INF into classes dir, didn't help me.
This is the error I get
3168 [main] WARN com.impetus.kundera.metadata.KunderaMetadataManager - No Entity metadata found for the class class kundega.rules.Rule. Any CRUD operation on this entity will fail.If your entity is for RDBMS, make sure you put fully qualified entity class name under <class></class> tag in persistence.xml for RDBMS persistence unit. Returning null value.
Exception in thread "main" com.impetus.kundera.KunderaException: java.lang.IllegalArgumentException: Entity object is invalid, operation failed. Please check previous log message for details
at com.impetus.kundera.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:174)
at kundega.rules.AppMain.main(AppMain.java:27)
Caused by: java.lang.IllegalArgumentException: Entity object is invalid, operation failed. Please check previous log message for details
at com.impetus.kundera.graph.ObjectGraphBuilder.getNode(ObjectGraphBuilder.java:101)
at com.impetus.kundera.graph.ObjectGraphBuilder.getObjectGraph(ObjectGraphBuilder.java:75)
at com.impetus.kundera.persistence.PersistenceDelegator.persist(PersistenceDelegator.java:135)
at com.impetus.kundera.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:168)
So here is my files.
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="UNIT">
<provider>com.impetus.kundera.KunderaPersistence</provider>
<class>kundega.rules.Rule</class>
<properties>
<property name="kundera.client.lookup.class" value="com.impetus.client.rdbms.RDBMSClientFactory" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql://130.230.141.228:3306/fastory" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="mysql" />
</properties>
</persistence-unit>
</persistence>
Start of Entity class
#Entity
#Table(name="eplrules", schema="fastory")
public class Rule {
#Id
//#GeneratedValue (strategy=GenerationType.AUTO)
#Column (name ="rule_id")
private long ruleId;
#Column (name ="rule")
private String rule;
Main class
public static void main(String[] args) {
System.out.println("start");
BasicConfigurator.configure();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("UNIT");
Rule r = new Rule();
r.setRuleId(103);
r.setRuleName("SomeRuleName");
r.setRule("SomeRule");
EntityManager em = emf.createEntityManager();
em.persist(r);
Query q = em.createQuery("select p from Rule p");
List<Rule> rules = q.getResultList();
em.close();
System.out.println(rules);
System.out.println("stop");
em.close();
emf.close();
}
When I got this I checked:
<class>package.name.DaoClass</class>
was defined in persistence.xml, this resolved the error. Also check
<property name="kundera.annotations.scan.package" value="package.name"/>
matches correctly to your package name.
"kundega.rules.Rule" package name is correct? Or is it "kundera.rules.Rule" ?

NHibernateHelper - many tables

I am new in NHibernate, I have based on tutorial: http://nhibernate.info/doc/tutorials/first-nh-app/your-first-nhibernate-based-application.html . So I have NHibernateHelper:
public class NHibernateHelper {
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof (Product).Assembly);
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
} }
But I have also entity Category and User? Do I need each entity add to configuration using code AddAssembly?? Because when I have added code:
configuration.AddAssembly(typeof (Product).Assembly);
configuration.AddAssembly(typeof(Category).Assembly);
I have error:
Could not compile the mapping document: MvcApplication1.Mappings.Product.hbm.xml
First check whether you have set the "Build Action" of all the mapping files (*.hbm.xml) to "Embedded Resource". This is VERY important.
Then you only need to add a call to AddAssembly once as NHibernate is clever enough to scan through the assembly to sniff out all your entities that map to all your embedded hbm.xml files..
e.g. You only need to supply the assembly once that contains all your entities:-
_configuration.AddAssembly(typeof (Product).Assembly);
NHibernate will now find Category (and all others) automatically as long as they are in the same assembly as Product. HTH
you can alternatively add the mapping tag into the web.config, instead of adding it in code on the SessionFactory initialization. Then, your code will look like this:
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
And in the web config you will have to indicate the assembly where all of your mappings are, like this:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="dialect">
NHibernate.Dialect.MsSql2005Dialect
</property>
<property name="connection.driver_class">
NHibernate.Driver.SqlClientDriver
</property>
<property name="connection.connection_string">
-- YOUR STRING CONNECTION --
</property>
<property name="proxyfactory.factory_class">
NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
<mapping assembly="You.Assembly.Namespace" />
</session-factory>
Being the important configuration tag "mapping assembly="Your.Assembly.Namespace". As the other contributor mentioned before, it is very important that you mark each of the hbm.xml file as embedded resource, otherwise it will be as you never created it. By doing this, you just need to create all of the mappings inside of this assembly (project) and those will be automatically read when NH configures.

Use JAAS for LDAP password with Spring security

I have a Java EE web application which uses an LDAP authentication. I use Spring security to connect to my LDAP with the following code:
<bean id="ldapContextSource" class="com.myapp.security.authentication.MySecurityContextSource">
<constructor-arg index="0" value="${ldap.url}" />
<constructor-arg index="1" ref="userConnexion" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
<bean id="userConnexion" class="com.myapp.util.security.WebsphereCredentials">
<constructor-arg value="${ldap.authJndiAlias}" />
</bean>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="ldapContextSource" />
<property name="userSearch" ref="userSearch" />
</bean>
</constructor-arg>
<constructor-arg>
<bean class="com.myapp.security.authentication.MyAuthoritiesPopulator" >
<property name="userService" ref="userService" />
</bean>
</constructor-arg>
<property name="userDetailsContextMapper" ref="myUserDetailsContextMapper"/>
<property name="hideUserNotFoundExceptions" value="false" />
</bean>
Actually, my bean WebsphereCredentials uses a WebSphere private class WSMappingCallbackHandlerFactory as in this response : How to access authentication alias from EJB deployed to Websphere 6.1
We can see it in the official websphere documentation: http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frsec_pluginj2c.html
But I don't want it because:
I think my application can access all JAAS logins in my WebSphere instance (not sure).
This class is defined in the HUGE IBM client library com.ibm.ws.admin.client-7.0.0.jar (42 Mo) => compilation slower, not present in my enterprise nexus
It's not portable, not standard
For information, I define the WebsphereCredentials constructor as this:
Map<String, String> map = new HashMap<String, String>();
map.put(Constants.MAPPING_ALIAS, this.jndiAlias);
Subject subject;
try {
CallbackHandler callbackHandler = WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map, null);
LoginContext lc = new LoginContext("DefaultPrincipalMapping", callbackHandler);
lc.login();
subject = lc.getSubject();
} catch (NotImplementedException e) {
throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
} catch (LoginException e) {
throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
}
PasswordCredential cred = (PasswordCredential) subject.getPrivateCredentials().toArray()[0];
this.user = cred.getUserName();
this.password = String.valueOf(cred.getPassword());
Is there a way to use just Spring security and remove this dependency?
I have no idea how to combine http://static.springsource.org/spring-security/site/docs/3.1.x/reference/jaas.html and http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ldap.html.
Maybe I must totally change my approach and use another way?
I assume your goal is to simply utilize the username / password that you configure in WebSphere to connect to the LDAP directory? If this is the case, you are not really trying to combine LDAP and JAAS based authentication. The JAAS support is really intended to be a way of using JAAS LoginModules to authenticate a user instead of using the LDAP based authentication.
If you are wanting to obtain the username and password without having a compile time dependency on WebSphere, you have a few options.
Eliminating Compile Time and Runtime Dependencies on WAS
One option is to configure the password in a different way. This could be as simple as using the password directly directly in the configuration file as shown in the Spring Security LDAP documentation:
<bean id="ldapContextSource"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<constructor-arg value="ldap://monkeymachine:389/dc=springframework,dc=org"/>
<property name="userDn" value="cn=manager,dc=springframework,dc=org"/>
<property name="password" value="password"/>
</bean>
You could also configure the username password in JNDI. Another alternative is to use a .properties file with the Property. If you are wanting to ensure the password is secured, then you will probably want to encrypt the password using something like Jasypt.
Eliminating Compile Time dependencies and still configuring with WAS
If you need or want to use WebSphere's J2C support for storing the credentials, then you can do by injecting the CallbackHandler instance. For example, your WebsphereCredentials bean could be something like this:
try {
LoginContext lc = new LoginContext("DefaultPrincipalMapping", this.callbackHandler);
lc.login();
subject = lc.getSubject();
} catch (NotImplementedException e) {
throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
} catch (LoginException e) {
throw new EfritTechnicalException(EfritTechnicalExceptionEnum.LOGIN_CREDENTIAL_PROBLEM, e);
}
PasswordCredential cred = (PasswordCredential) subject.getPrivateCredentials().toArray()[0];
this.user = cred.getUserName();
this.password = String.valueOf(cred.getPassword());
Your configuration would then look something like this:
<bean id="userConnexion" class="com.myapp.util.security.WebsphereCredentials">
<constructor-arg ref="wasCallbackHandler"/>
</bean>
<bean id="wasCallbackHandler"
factory-bean="wasCallbackFactory"
factory-method="getCallbackHandler">
<constructor-arg>
<map>
<entry
value="${ldap.authJndiAlias}">
<key>
<util:constant static-field="com.ibm.wsspi.security.auth.callback.Constants.MAPPING_ALIAS"/>
</key>
</entry>
</map>
</constructor-arg>
<constructor-arg>
<null />
</constructor-arg>
</bean>
<bean id="wasCallbackFactory"
class="com.ibm.wsspi.security.auth.callback.WSMappingCallbackHandlerFactory"
factory-method="getInstance" />
Disclaimer
CallbackHandler instances are not Thread safe and generally should not be used more than once. Thus it can be a bit risky injecting CallbackHandler instances as member variables. You may want to program in a check to ensure that the CallbackHandler only used one time.
Hybrid Approach
You could do a hybrid approach that always removes the compile time dependency and allows you to remove the runtime dependency in instances where you might not be running on WebSphere. This could be done by combining the two suggestions and using Spring Bean Definition Profiles to differentiate between running on WebSphere and a non-WebSphere machine.

Configuring Fluent NHibernate from NHibernate config section

I'm trying to use Fluent NHibernate in my solution by configuring it with the following NHibernate xml configuration section
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="mitre">
<property name="dialect">NHibernate.Dialect.Oracle9iDialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="connection.connection_string">Data Source=YOUR_DB_SERVER;Database=Northwind;User ID=YOUR_USERNAME;Password=YOUR_PASSWORD;</property>
<property name="connection.isolation">ReadCommitted</property>
<property name="default_schema">TRATE</property>
<!-- HBM Mapping Files -->
<mapping assembly="Markel.Mint.Mitre.Data" />
</session-factory>
</hibernate-configuration>
In my code file, to instantiate ISession:
NH_Cfg.Configuration cfg = new NH_Cfg.Configuration();
cfg.Configure();
Fluently.Configure(cfg).Mappings(m => m.FluentMappings = ????)
My question is that if I have already specified the assembly in the NHibernate config section, do I need to explicitly set FluentMappings? If so, then is it possible to retrieve this data from NHibernate config programmatically?
Thanks
Oz
The mapping assembly in hibernate.cfg.xml is searched for embedded *.hbm.xml files. NHibernate does not know anything about fluent mappings (e.g. ClassMap) as those are introduced by Fluent NHibernate. So you need:
Fluently.Configure(cfg).Mappings(m => m.FluentMappings.AddFromAssemblyOf<SomeDomainType>();
in order to configure NHibernate using your ClassMap mappings.
Thanks for the quick response, James.
Could I do the following then?
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="mitre">
<property name="dialect">NHibernate.Dialect.Oracle9iDialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.OracleDataClientDriver</property>
<property name="connection.connection_string">Data Source=YOUR_DB_SERVER;Database=Northwind;User ID=YOUR_USERNAME;Password=YOUR_PASSWORD;</property>
<property name="connection.isolation">ReadCommitted</property>
<property name="default_schema">TRATE</property>
<property name="fluent.nhibernate.fluentmapping">Markel.Mint.Mitre.Core.Domain</property>
</session-factory>
</hibernate-configuration>
Then my code could refer to the property thus:
NH_Cfg.Configuration cfg = new NH_Cfg.Configuration(); cfg.Configure();
Fluently.Configure(cfg).Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.Load(cfg.Properties["fluent.nhibernate.fluentmapping"])));