I am doing an application in springs with maven. i wrote all properties in app.properties file
file structure is like this
src/main/resource
|_
| templates
| |_mytempaltefile.vm
|_ app.properties
i gave the path(absloute) in app.property
app.properties file
template.base.path=D\:/SVN/trunk/tfbdirect/src/main/resources/templates
utilities-spring.xml
<bean id="velocityEngine"
class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="velocityProperties">
<props>
<prop key="resource.loader">file</prop>
<prop key="file.resource.loader.class">
org.apache.velocity.runtime.resource.loader.FileResourceLoader
</prop>
<prop key="file.resource.loader.path">${template.base.path}</prop>
<prop key="file.resource.loader.cache">false</prop>
</props>
</property>
</bean>
my class
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.ui.velocity.VelocityEngineUtils;
import com.providerpay.tfbdirect.service.mail.MailSenderService;
public class LoginServiceImpl implements ILoginService{
/**
* Injected through Spring IOC
*/
ILoginDAO loginDAO;
ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl;
PlatformTransactionManager txmanager;
//IForgotPasswordDAO forgotPasswordDAO;
private VelocityEngine velocityEngine;
private String appURL;
private MailSenderService mailSenderService;
TFBLogger log = TFBLoggerFactory.getLogger(RuleServer.class);
public String getAppURL() {
return appURL;
}
public void setAppURL(String appURL) {
this.appURL = appURL;
}
public MailSenderService getMailSenderService() {
return mailSenderService;
}
public VelocityEngine getVelocityEngine() {
return velocityEngine;
}
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
public void setMailSenderService(MailSenderService mailSenderService) {
this.mailSenderService = mailSenderService;
}
public ILoginDAO getLoginDAO() {
return loginDAO;
}
public void setLoginDAO(ILoginDAO loginDAO) {
this.loginDAO = loginDAO;
}
public ClaimRuleProcessServiceImpl getClaimRuleProcessServiceImpl() {
return claimRuleProcessServiceImpl;
}
public void setClaimRuleProcessServiceImpl(
ClaimRuleProcessServiceImpl claimRuleProcessServiceImpl) {
this.claimRuleProcessServiceImpl = claimRuleProcessServiceImpl;
}
public void setTxmanager(PlatformTransactionManager txmanager) {
this.txmanager = txmanager;
}
/**
* Validates Login
* #param loginView
* #return
*/
public boolean isValidLogin(LoginView loginView) {
/* create tx definition object */
DefaultTransactionDefinition paramTransactionDefinition = new DefaultTransactionDefinition();
TransactionStatus status = txmanager.getTransaction(paramTransactionDefinition );
boolean result = false;
try{
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
Feedback feedback = claimRuleProcessServiceImpl.validateClaimEligibility(loginEntity);
log.info( "Rule executed was " +feedback.getAll());
for (FeedbackMessage feedbackmessaage :feedback.getAll())
{
log.info("\n--------------");
log.info(feedbackmessaage.getRuleCd());
log.info(feedbackmessaage.getMessage());
log.info(feedbackmessaage.getSeverity().getName());
log.info("\n--------------");
}
result = loginDAO.isValidLogin(loginEntity);
log.debug("result = {}", result);
txmanager.commit(status);
}catch(Exception e){
txmanager.rollback(status);
throw new TfbException("Error occured while validating login credentials");
}
return result;
}
#Autowired
VelocityEngine velocityengine;
public boolean mailResetLink(LoginView loginView) {
String toEmailAddress;
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
/* getting user Email from DAO*/
toEmailAddress = loginDAO.getEmailByUsername(loginEntity);
if(toEmailAddress != null && toEmailAddress.trim().length() > 0)
{
Map<String, Object> model = new HashMap<String, Object>();
model.put("user", loginEntity);
model.put("appURL", appURL);
String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, "emailTemplate.vm","UTF-8", model);
mailSenderService.sendMail("from mail", toEmailAddress, "Password Reset Link",body);
}
else
{
return false;
}
return true;
}
public boolean resetPassword(LoginView loginView)
{
LoginEntity loginEntity = BeanMapper.INSTANCE.viewToEntityMapper(loginView);
return loginDAO.resetPassword(loginEntity);
}
}
every thing fine but i need to change the absolute path to relative path.. i tried many ways.
i tried like following
template.base.path=/templates/
but still getting below error .
ResourceManager : unable to find resource 'emailTemplate.vm' in any resource loader.
can any one help me..
Thanks in advance
You are falling into a common pitfall when using velocity with spring : you place your templates in one location and use a resource loader that searches them in another place. So you have 2 common usages :
put templates in classpath (as you do) and use ClasspathResourceLoader
resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
it is simple with little dependencies, but it forces you to put templates in classpath ...
put templates under WEB-INF (as you would do for JSPs) and use WebappResourceLoader from velocity tools
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path=/WEB-INF/velocity/
it is more natural for a template location, but you add a dependency on velocity tools.
And let spring manage dependencies but not instanciating via new ...
I had the same problem recently with karaf OSGi framework.
In a CXF resource class (Login in this context) you have to initialize the Velocity Engine like this:
public Login() {
/* first, get and initialize an engine */
ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
}
Then, in the web method, instantiate the template:
/* create a context and add data */
synchronized (initLock) {
if (loginTemplate == null) {
loginTemplate = ve.getTemplate("templates/login.vm");
}
}
VelocityContext context = new VelocityContext();
Unfortunately, it didn't work out to load the template immediately after the ve.init() call in the constructor.
Your configuration seems correct. If you instantiate the VelocityEngine instance using "new", try following:
#Autowired
VelocityEngine velocityEngine;
Related
While calling getTemplate() method it's throwing this error -
"Error resolving template [betreff_product_request], template might not exist or might not be accessible by any of the configured Template Resolvers".
Is it because of the wrong path I've mentioned in templateResolver.setPrefix("D:\\templates\\");?.
How can I solve this?
public class MailerTemplateEngine {
private final TemplateEngine templateEngine;
public MailerTemplateEngine() {
this.templateEngine = new org.thymeleaf.TemplateEngine();
FileTemplateResolver templateResolver = new FileTemplateResolver ();
templateResolver.setPrefix("D:\\templates\\");
templateResolver.setSuffix(".txt");
templateResolver.setTemplateMode(TemplateMode.TEXT);
templateResolver.setOrder(templateEngine.getTemplateResolvers().size());
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setCacheable(false);
templateResolver.setCheckExistence(true);
this.templateEngine.setTemplateResolver(templateResolver);
}
public String getTemplate(String templateName, HashMap<String,String> parameters) {
Context ctx = new Context();
if (parameters != null) {
parameters.forEach((k, v) -> {
ctx.setVariable(k, v);
});
}
return this.templateEngine.process(templateName, ctx).trim();
}
}
I am trying to use CDI, using #Inject for dependency injection but my object stays null and won't initialize... more precisely:
I have a webapplication with WeatherController which use a java application with all my modules. In the Java application I have a ForecastService where I try to initialize my repositories with CDI without success.
I tried/searched a lot. Hopefully somebody can help me here?
I have a web application which uses this controller:
#Path("/weather")
public class WeatherController {
private ForecastService forecastService;
//private ForecastRepository forecastRepository = new ForecastFakeDB();
//private ObservationRepository observationRepository = new ObservationFakeDB();
public WeatherController() {
//this.forecastService.setForecastRepository(forecastRepository);
//forecastService.setObservationRepository(observationRepository);
forecastService = new ForecastService();
}
//localhost:8080/DA_project_weatherPredictions/api/weather/observation/Leuven
#GET
#Produces({"application/json"})
#Path("/observation/{location}")
public Response getObservation(#PathParam("location") String location) {
try {
ObjectMapper mapper = new ObjectMapper();
Observation observation = forecastService.getCurrentObservation(location);
//Object to JSON in String
String jsonInString = mapper.writeValueAsString(observation);
return Response.status(200).entity(jsonInString).build();
} catch (Exception ex) {
System.out.println("error");
System.out.println(ex.getMessage());
ex.printStackTrace();
return null;
}
}
This works perfectly. This is my forecastService:
public class ForecastService implements Service {
#Inject
ForecastRepository forecastRepository;
#Inject
ObservationRepository observationRepository;
private Client client;
private WebTarget webTargetObservation, webTargetForecast;
public ForecastService() {
// WeatherRepositoryFactory weatherRepositoryFactory = new WeatherRepositoryFactory();
// forecastRepository = weatherRepositoryFactory.getForecastRepository(repository);
// observationRepository = weatherRepositoryFactory.getObservationRepository(repository);
loadWeather();
}
public void setForecastRepository(ForecastRepository forecastRepository) {
this.forecastRepository = forecastRepository;
}
public void setObservationRepository(ObservationRepository observationRepository) {
this.observationRepository = observationRepository;
}
public void loadWeather() {
//http://api.openweathermap.org/data/2.5/weather?units=metric&appid=12fa8f41738b72d954b6758d48e129aa&q=BE,Leuven
//http://api.openweathermap.org/data/2.5/forecast?units=metric&appid=12fa8f41738b72d954b6758d48e129aa&q=BE,Leuven
client = ClientBuilder.newClient();
webTargetObservation = client.target("http://api.openweathermap.org/data/2.5/weather")
.queryParam("mode", "json")
.queryParam("units", "metric")
.queryParam("appid", "12fa8f41738b72d954b6758d48e129aa");
webTargetForecast = client.target("http://api.openweathermap.org/data/2.5/forecast")
.queryParam("mode", "json")
.queryParam("units", "metric")
.queryParam("appid", "12fa8f41738b72d954b6758d48e129aa");
}
public Observation getCurrentObservation(String location) throws Exception {
Observation observation;
observation = observationRepository.getObservation(location);
if (observation == null) {
try {
//observation = webTargetObservation.queryParam("q", location).request(MediaType.APPLICATION_JSON).get(Observation.class);
Response response = webTargetObservation.queryParam("q", location).request(MediaType.APPLICATION_JSON).get();
String json = response.readEntity(String.class);
//System.out.println(json);
response.close();
observation = new ObjectMapper().readValue(json, Observation.class);
//System.out.println(observation.getWeather().getDescription());
}
catch (Exception e){
StringBuilder sb = new StringBuilder(e.toString());
for (StackTraceElement ste : e.getStackTrace()) {
sb.append("\n\tat ");
sb.append(ste);
}
String trace = sb.toString();
throw new Exception (trace);
//throw new Exception("Location not found");
}
this.observationRepository.addObservation(observation, location);
}
return observation;
}
So the problem is that my repositories stay null
#Alternative
public class ObservationDB implements ObservationRepository{
//as ID we can use the ASCI value of the String key .. example uklondon to ASCII
public ObservationDB(String name) {
}
#Override
public Observation getObservation(String location) {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void addObservation(Observation observation, String location) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Mermory DB:
#Default
public class ObservationFakeDB implements ObservationRepository {
//example String key : beleuven, uklondon
private static Map<String, Observation> observations;
public ObservationFakeDB() {
observations = new HashMap<>();
}
#Override
public Observation getObservation(String location) {
return observations.get(location);
}
#Override
public void addObservation(Observation observation, String location) {
observations.put(location, observation);
}
}
I have a beans.xml, I thought beans.xml, #Inject, #Default en #Alternative would make this work. I tried #Dependent, #Applicationscoped.
EDIT:
I also often get this warning on Netbeans.
My beans.xml
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>
You need to let your CDI container manages the lifecycle of all your beans to allow it to resolve and inject properly their dependencies.
So, in your case you should not create yourself the instance of ForecastService, you should rather delegate it to the CDI container by simply annotating the field forecastService with #Inject this way its dependencies will be automatically resolved and set by the container.
public class WeatherController {
#Inject
private ForecastService forecastService;
...
I've come up with a working dynamic multi-tenant application using:
Java 8
Java Servlet 3.1
Spring 3.0.7-RELEASE (can't change the version)
Hibernate 3.6.0.Final (can't change the version)
Commons dbcp2
This is the 1st time I've had to instantiate Spring objects myself so I'm wondering if I've done everything correctly or if the app will blow up in my face at an unspecified future date during production.
Basically, the single DataBase schema is known, but the database details will be specified at runtime by the user. They are free to specify any hostname/port/DB name/username/password.
Here's the workflow:
The user logs in to the web app then either chooses a database from a known list, or specifies a custom database (hostname/port/etc.).
If the Hibernate SessionFactory is built successfully (or is found in the cache), then it's persisted for the user's session using SourceContext#setSourceId(SourceId) then the user can work with this database.
If anybody choses/specifies the same database, the same cached AnnotationSessionFactoryBean is returned
The user can switch databases at any point.
When the user switches away from a custom DB (or logs off), the cached AnnotationSessionFactoryBeans are removed/destroyed
So will the following work as intended? Help and pointers are most welcome.
web.xml
<web-app version="3.1" ...>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener> <!-- Needed for SourceContext -->
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<web-app>
applicationContext.xml
<beans ...>
<tx:annotation-driven />
<util:properties id="db" location="classpath:db.properties" /> <!-- driver/url prefix -->
<context:component-scan base-package="com.example.basepackage" />
</beans>
UserDao.java
#Service
public class UserDao implements UserDaoImpl {
#Autowired
private TemplateFactory templateFactory;
#Override
public void addTask() {
final HibernateTemplate template = templateFactory.getHibernateTemplate();
final User user = (User) DataAccessUtils.uniqueResult(
template.find("select distinct u from User u left join fetch u.tasks where u.id = ?", 1)
);
final Task task = new Task("Do something");
user.getTasks().add(task);
TransactionTemplate txTemplate = templateFactory.getTxTemplate(template);
txTemplate.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
template.save(task);
template.update(user);
}
});
}
}
TemplateFactory.java
#Service
public class TemplateFactory {
#Autowired
private SourceSessionFactory factory;
#Resource(name = "SourceContext")
private SourceContext srcCtx; // session scope, proxied bean
#Override
public HibernateTemplate getHibernateTemplate() {
LocalSessionFactoryBean sessionFactory = factory.getSessionFactory(srcCtx.getSourceId());
return new HibernateTemplate(sessionFactory.getObject());
}
#Override
public TransactionTemplate getTxTemplate(HibernateTemplate template) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(template.getSessionFactory());
return new TransactionTemplate(txManager);
}
}
SourceContext.java
#Component("SourceContext")
#Scope(value="session", proxyMode = ScopedProxyMode.INTERFACES)
public class SourceContext {
private static final long serialVersionUID = -124875L;
private SourceId id;
#Override
public SourceId getSourceId() {
return id;
}
#Override
public void setSourceId(SourceId id) {
this.id = id;
}
}
SourceId.java
public interface SourceId {
String getHostname();
int getPort();
String getSID();
String getUsername();
String getPassword();
// concrete class has proper hashCode/equals/toString methods
// which use all of the SourceIds properties above
}
SourceSessionFactory.java
#Service
public class SourceSessionFactory {
private static Map<SourceId, AnnotationSessionFactoryBean> cache = new HashMap<SourceId, AnnotationSessionFactoryBean>();
#Resource(name = "db")
private Properties db;
#Override
public LocalSessionFactoryBean getSessionFactory(SourceId id) {
synchronized (cache) {
AnnotationSessionFactoryBean sessionFactory = cache.get(id);
if (sessionFactory == null) {
return createSessionFactory(id);
}
else {
return sessionFactory;
}
}
}
private AnnotationSessionFactoryBean createSessionFactory(SourceId id) {
AnnotationSessionFactoryBean sessionFactory = new AnnotationSessionFactoryBean();
sessionFactory.setDataSource(new CutomDataSource(id, db));
sessionFactory.setPackagesToScan(new String[] { "com.example.basepackage" });
try {
sessionFactory.afterPropertiesSet();
}
catch (Exception e) {
throw new SourceException("Unable to build SessionFactory for:" + id, e);
}
cache.put(id, sessionFactory);
return sessionFactory;
}
public void destroy(SourceId id) {
synchronized (cache) {
AnnotationSessionFactoryBean sessionFactory = cache.remove(id);
if (sessionFactory != null) {
if (LOG.isInfoEnabled()) {
LOG.info("Releasing SessionFactory for: " + id);
}
try {
sessionFactory.destroy();
}
catch (HibernateException e) {
LOG.error("Unable to destroy SessionFactory for: " + id);
e.printStackTrace(System.err);
}
}
}
}
}
CustomDataSource.java
public class CutomDataSource extends BasicDataSource { // commons-dbcp2
public CutomDataSource(SourceId id, Properties db) {
setDriverClassName(db.getProperty("driverClassName"));
setUrl(db.getProperty("url") + id.getHostname() + ":" + id.getPort() + ":" + id.getSID());
setUsername(id.getUsername());
setPassword(id.getPassword());
}
}
In the end I extended Spring's AbstractRoutingDataSource to be able to dynamically create datasources on the fly. I'll update this answer with the full code as soon as everything is working correctly. I have a couple of last things to sort out, but the crux of it is as follows:
#Service
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
// this is pretty much the same as the above SourceSessionFactory
// but with a map of CustomDataSources instead of
// AnnotationSessionFactoryBeans
#Autowired
private DynamicDataSourceFactory dataSourceFactory;
// This is the sticky part. I currently have a workaround instead.
// Hibernate needs an actual connection upon spring startup & there's
// also no session in place during spring initialization. TBC.
// #Resource(name = "UserContext") // scope session, proxy bean
private UserContext userCtx; // something that returns the DB config
#Override
protected SourceId determineCurrentLookupKey() {
return userCtx.getSourceId();
}
#Override
protected CustomDataSource determineTargetDataSource() {
SourceId id = determineCurrentLookupKey();
return dataSourceFactory.getDataSource(id);
}
#Override
public void afterPropertiesSet() {
// we don't need to resolve any data sources
}
// Inherited methods copied here to show what's going on
// #Override
// public Connection getConnection() throws SQLException {
// return determineTargetDataSource().getConnection();
// }
//
// #Override
// public Connection getConnection(String username, String password)
// throws SQLException {
// return determineTargetDataSource().getConnection(username, password);
// }
}
So I just wire up the DynamicRoutingDataSource as the DataSource for Spring's SessionFactoryBean along with a TransactionManager an all the rest as usual. As I said, more code to follow.
I have an activity class that is annotated as a component that calls an action class:
#Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request)
{
actionExecutionContext = action.execute(actionExecutionContext);
}
My action class is also annotated with #Component and has the following execute method:
#Transactional(propagation = Propagation.MANDATORY)
#Override
public ActionExecutionContext execute(ActionExecutionContext actionExecutionContext)
{
iogl = ioglDao.create(iogl);
return actionExecutionContext;
}
The ioglDao class is annotated as #Repository and has the following create method:
#Transactional(propagation = Propagation.MANDATORY)
#Override
public InventoryOwnerGroupLocation create(InventoryOwnerGroupLocation iogl)
{
// injected
Session session = sessionFactory.getCurrentSession();
session.save(iogl);
return iogl;
}
I believe that the Transaction should propagate from the Service Layer to the dao class, but it seems it's not. I get the No existing transaction found for transaction marked with propagation 'mandatory' Exception.
Why isn't the transaction propagating to my DAO classes?
EDIT: added all of the activity class
#Service("FASelfServiceMappingService")
#Component
public class ExecuteTemplateActivity extends Activity
{
private final static Logger logger = Logger.getLogger(ExecuteTemplateActivity.class);
// mapper framework to interact with DynamoDB database
private final DynamoDBMapper dynamoDBMapper;
// class to convert external models to internal models
private final InternalModelToDynamoDBModelConverter internalToDynamoDBConverter;
private final InternalModelToOracleModelConverter internalToOracleConverter;
private final CoralModelToInternalModelConverter coralToInternalConverter;
// class to generate list of actions
private final ActionGenerator actionGenerator;
// status constants
private static final String STATUS_COMPLETED = "COMPLETED";
private static final String STATUS_FAILED = "FAILED";
#Inject
public ExecuteTemplateActivity(InternalModelToDynamoDBModelConverter internalToDynamoDBConverter,
InternalModelToOracleModelConverter internalToOracleConverter,
CoralModelToInternalModelConverter coralToInternalConverter,
ActionGenerator actionGenerator,
DynamoDBMapper dynamoDBMapper)
{
this.internalToDynamoDBConverter = internalToDynamoDBConverter;
this.internalToOracleConverter = internalToOracleConverter;
this.coralToInternalConverter = coralToInternalConverter;
this.actionGenerator = actionGenerator;
this.dynamoDBMapper = dynamoDBMapper;
}
#Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
#Operation("ExecuteTemplate")
public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request) throws RetryableException, NonRetryableException
{
try
{
logger.info("Input given: " + request);
// convert request input to an internal request
Request internalRequest = coralToInternalConverter.coralRequestToInternal(request);
logger.info("Successfully converted External Request to internal Request.");
String templateName = getTemplateName(internalRequest);
logger.info("Template Name extracted from the request: " + templateName);
Template template = getTemplateFromDynamo(internalRequest, templateName);
logger.info("Template read from dynamoDB table: " + template);
// Generate a map from string to Action objects associated with the retrieved template
List<Action> listOfActions = actionGenerator.generateActions(template.getActions());
logger.info("Actions generated for template " + templateName + ": " + listOfActions);
// Generate the action context for actions to pass to each other to keep track of state
ActionExecutionContext actionExecutionContext = internalToOracleConverter.inputsToActionExecutionContext(internalRequest.getInputs());
logger.info("Built ActionExecutionContext:" + actionExecutionContext);
// execute the actions
for (Action action : listOfActions)
{
actionExecutionContext = action.execute(actionExecutionContext);
}
logger.info("All actions executed successfully.");
// request was completed successfully, create request in Request table
String requestId = createRequestInDynamo(internalRequest, STATUS_COMPLETED);
ExecuteTemplateResponse executeTemplateResponse = new ExecuteTemplateResponse();
executeTemplateResponse.setRequestId(requestId);
logger.info("Service call "+ this.getClass() +" succeeded.");
return executeTemplateResponse;
}
catch (RetryableException re)
{
logger.error("Retryable Exception occurred in activity.", re);
throw re;
}
catch (NonRetryableException nre)
{
logger.error("NonRetryable Exception occurred in activity.", nre);
throw nre;
}
catch (Exception e)
{
logger.error("Unknown Exception occurred in activity.", e);
throw new NonRetryableException("Unexpected error", e);
}
}
/**
* extracts the templateName from the internalRequest
* #param internalRequest internal model of the request
* #return templateName
*/
private String getTemplateName(Request internalRequest)
{
Validate.notNull(internalRequest, "internalRequest must not be null.");
String templateName;
try
{
// extract template name from request
templateName = internalRequest.getTemplateName();
Validate.notNull(templateName, "templateName must not be null.");
}
catch (IllegalArgumentException iae)
{
createRequestInDynamo(internalRequest, STATUS_FAILED);
logger.error("Invalid input: templateName is null.");
throw new NonRetryableException("Invalid input: templateName is null.", iae);
}
return templateName;
}
/**
* Retrieves the template object associated with given templateName
* #param internalRequest internal model of request
* #param templateName name of template to retrieve
* #return Template object
*/
private Template getTemplateFromDynamo(Request internalRequest, String templateName)
{
Validate.notNull(internalRequest, "internalRequest must not be null.");
Validate.notNull(templateName, "templateName must not be null.");
Template template;
try
{
// read the template with given template name from Templates table
template = dynamoDBMapper.load(Template.class, templateName);
}
catch (DynamoDBMappingException ddbme)
{
createRequestInDynamo(internalRequest, STATUS_FAILED);
logger.error("Reading template from dynamoDB table failed.", ddbme);
throw new NonRetryableException("Incorrect class annotation or incompatible with class", ddbme);
}
catch (AmazonClientException ace)
{
createRequestInDynamo(internalRequest, STATUS_FAILED);
logger.error("Reading template from dynamoDB table failed.", ace);
throw new RetryableException("Error when loading template from dynamoDB", ace);
}
return template;
}
EDIT:
Transaction Manager configuration:
<tx:annotation-driven transaction-manager="txManager"
mode="proxy" proxy-target-class='true' />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
I had the same exception with Spring WebFlux.
Issue :
repository.findByUserId(id);
Solution:
#Autowired
private TransactionTemplate transactionTemplate;
transactionTemplate.execute(transactionStatus -> identInformationRepository.findByUserId(id));
In some cases it can be solved with the following:
Try to separate the code from the transaction you are getting the error in, try to do the injection in a separate method, preferably at startup.
And add #Transactional before begin void
Example:
BEFORE
public void mainProces(){
System.out.println("Hello, i save my name");
SQL(select)
SQL(save)
}
AFTER
#Transactional
public void secondProces(){
SQL(save)
}
public void mainProces(){
System.out.println("Hello, i save my name");
secondProces();
SQL(select)
}
It is maybe a problem related to your Spring configuration. Did you follow the guide at http://docs.spring.io/autorepo/docs/spring/4.2.x/spring-framework-reference/html/transaction.html? Can you show how you configure Spring transaction management ?
I've created the ConfigAdmin loaded some properties. After that I've saved them. My question is: how can I get the properties that I have stored?
I've created the ConfigAdmin in the Activator.java:
public class Activator implements BundleActivator {
private String configFile = "API.properties";
#Override
public void start(BundleContext bundleContext) throws Exception {
InputStream stream = (bundleContext.getBundle().getResource(configFile)).openStream();
Properties properties = new Properties();
properties.load(stream);
createConfigAdmin(properties);
}
#Override
public void stop(BundleContext bundleContext) throws Exception {
}
private boolean createConfigAdmin(Properties properties, BundleContext context) {
try {
Dictionary<String, String> props = new Hashtable<String, String>();
ServiceReference reference = context.getServiceReference(ConfigurationAdmin.class.getName());
ConfigurationAdmin admin = (ConfigurationAdmin) context.getService(reference);
Configuration configuration = admin.createFactoryConfiguration(pid.configAdminPID, null);
for(final String name: properties.stringPropertyNames())
props.put(name, properties.getProperty(name));
configuration.update(props);
return true;
} catch(Exception e)
{
e.printStackTrace();
return false;
}
}
}
Was your intention really to create a factory config? You only need it if you want to create several configs for the same factory pid.
If you simply want to create a simple configuration then just use admin.getConfiguration(oid) you can update the configuration in the same way you do now.
If you want to read the configuration afterwards you simply get it again. If you want to configure a bundle with this configuration you typically will create a ManagedService and publish it. See http://liquid-reality.de/display/liquid/2011/09/23/Karaf+Tutorial+Part+2+-+Using+the+Configuration+Admin+Service