I followed the example of the page of primefaces (http://www.primefaces.org/showcase/ui/datatableLazy.jsf), and it worked but because the example is loading the list on the constructor it is no exactly lazy loading. I understand that is a dummy example, so on my bean I added this lines
private LazyDataModel<Ficha> lazyListFichas;
And my init funcion I changed some parts to this
#PostConstruct
public void init() {
System.out.println("Inicializando fichas");
tienePadres=false;
fichaDM.setFicha(new Ficha());
//obtenerFichas();
//lazyListFichas = new FichaLazyList(fichaDM.getFichas);
lazyListFichas = new FichaLazyList();
}
My FichaLazyList is like this
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.ejb.EJB;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import ec.edu.puce.biologia.dao.FichaDao;
import ec.edu.puce.biologia.util.LazySorter;
#ViewScoped
public class FichaLazyList extends LazyDataModel <Ficha> {
private static final long serialVersionUID = 1L;
private List<Ficha> fichas=new ArrayList<Ficha>();
#EJB
private FichaDao fichaDao;
public FichaLazyList() {
}
public FichaLazyList(List<Ficha> fichas) {
this.fichas = fichas;
}
#Override
public Ficha getRowData(String rowKey) {
for(Ficha ficha : fichas) {
if(ficha.getIdFicha().equals(rowKey))
return ficha;
}
return null;
}
#Override
public Object getRowKey(Ficha ficha) {
return ficha.getIdFicha();
}
#Override
public List<Ficha> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
List<Ficha> data = new ArrayList<Ficha>();
//filter
fichas = fichaDao.encontrarPagina(first, pageSize);
if(fichas==null){
System.out.println("Lista nula");
}
for(Ficha ficha : fichas) {
boolean match = true;
for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = filters.get(filterProperty);
String fieldValue = String.valueOf(ficha.getClass().getField(filterProperty).get(ficha));
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(Exception e) {
match = false;
}
}
if(match) {
data.add(ficha);
}
}
long total = fichaDao.contar();
System.out.println("xxx"+total);
//sort
if(sortField != null) {
Collections.sort(data, new LazySorter(sortField, sortOrder));
}
//rowCount
// int dataSize = data.size();
this.setRowCount((int) total);
//paginate
if(total > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + ((int) total % pageSize));
}
}
else {
return data;
}
}
public List<Ficha> getFichas() {
return fichas;
}
public void setFichas(List<Ficha> fichas) {
this.fichas = fichas;
}
}
I get this error,
ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/catalogoBiologia].[Faces Servlet]] (http-localhost-127.0.0.1-8080-1) Servlet.service() for servlet Faces Servlet threw exception: java.lang.NullPointerException
at ec.edu.puce.biologia.model.FichaLazyList.load(FichaLazyList.java:55) [classes:]
Line 55 is this
fichas = fichaDao.encontrarPagina(first, pageSize);
Should it be viewscope or session scope, What am I doing wrong when I try to inject the ejb
So thanks Balusc, I was only calling it in my function with new. I changed value="#{taxonomiaController.lazyListFichas}" from my datatable to value="#{fichaLazyList}", In my head I didnt see FichaLazyList as a bean, it was another class, anyways that solved the problem and, I added #ManagedBean and #RequestScoped to FichaLazyList I guess it could be also #viewScoped. It seemed to me that should be RequestedScoped, if not I ll fix this.
Also I added this to the init function, it is another approach using an anoymous class:
lazyListFichas = new LazyDataModel() {
#Override
public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters){
List<Ficha> lazyFicha = new ArrayList<Ficha>();
lazyFicha = servicioFicha.obtenerTodos(first, pageSize);
// populateLazyRandomCars(lazyFicha, pageSize);
return lazyFicha;
}
};
/**
* In a real application, this number should be resolved by a projection
* query
*/
lazyListFichas.setRowCount((int) servicioFicha.contarRegistrosTotal());
I think the problem is not in your managed bean,the problem is in your model EJB or Hibernate
because the value of fichas is null so fichaDao.encontrarPagina(first, pageSize) returns null check the code of fichaDao and your hibernate settings to connect to database.
Related
I want to build a Java agent with Byte Buddy, which intercepts JDBC connection creation and closing event. I want to support data sources such as HikariCP, DBCP, etc, also plain JDBC with RDBMS drivers.
My code:
Instrumention setup
new AgentBuilder.Default()
.type(startMatcher.and(isSubTypeOf(java.sql.Connection.class).and(not(isAbstract())))
.transform(constructorTransformer).transform(methodsTransformer).with(listener).installOn(inst);
Intercepting code
package org.wxt.xtools.agents.jdbcmon;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import org.wxt.xtools.agents.utils.StringUtils;
import org.wxt.xtools.agents.utils.TopN;
import ch.qos.logback.classic.Logger;
import io.prometheus.client.Histogram;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.This;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
/**
*
* #author ggfan
*
*/
public class JDBCAPIInterceptor {
// ***ATTENTION*** fields below must be public, as we will access them from the
// intercepting methods
public static Map<Integer, ConnectionInfo> conns = new HashMap<Integer, ConnectionInfo>();
public static Map<String, String> stacks = new HashMap<String, String>();
public static Map<String, Integer> counstsByStack = new HashMap<String, Integer>();
public static TopN<StatementExecutionInfo> slowStatements = new TopN<StatementExecutionInfo>(10, new Comparator<StatementExecutionInfo>() {
#Override
public int compare(StatementExecutionInfo o1, StatementExecutionInfo o2) {
long d1 = o1.getExecutionEndTime() - o1.getExecutionStartTime();
long d2 = o2.getExecutionEndTime() - o2.getExecutionStartTime();
return Long.compare(d1, d2);
}
});
public static Logger log = JDBCMonitor.log;
public static JDBCStatsReport getInfo() {
JDBCStatsReport report = new JDBCStatsReport();
List<ConnectionInfo> data = new ArrayList<ConnectionInfo>();
for (ConnectionInfo ci : conns.values()) {
ConnectionInfo copy = new ConnectionInfo();
copy.setHash(ci.getHash());
copy.setStackHash(ci.getStackHash() + "(" + counstsByStack.get(ci.getStackHash()) + ")");
copy.setCreationTime(ci.getCreationTime());
copy.setLastActiveTime(ci.getLastActiveTime());
copy.setLastMethod(ci.getLastMethod());
copy.setCurrentStatement(ci.getCurrentStatement());
data.add(copy);
}
report.setConnectionInfo(data);
report.setSlowStatementTopN(slowStatements);
return report;
}
#RuntimeType
public static Object interceptor(#Origin Class<?> clazz, #Origin Method method, #SuperCall Callable<?> callable,
#net.bytebuddy.implementation.bind.annotation.This Object inst, #AllArguments Object[] args)
throws Exception {
// this is equal to original method, will not cause inner calls to other
// matching methods get intercepted.
// Object o = callable.call();
log.debug("intercepting {}#{}", clazz.getName(), method.getName());
int hashCode = System.identityHashCode(inst);
if (java.sql.Connection.class.isAssignableFrom(clazz)) {
ConnectionInfo ci = conns.get(hashCode);
// TODO fix bug here!!!
if (ci == null) {
log.debug("connection#{} is not in records anymore, maybe called #{} after close, ignored", hashCode,
method.getName());
}
return interceptConnectionMethods(method, hashCode, ci, callable, args);
} else if (java.sql.Statement.class.isAssignableFrom(clazz)) {
return interceptStatementMethods(method, hashCode, callable, args);
} else if (java.sql.PreparedStatement.class.isAssignableFrom(clazz)) {
return interceptStatementMethods(method, hashCode, callable, args);
} else if (java.sql.CallableStatement.class.isAssignableFrom(clazz)) {
return interceptStatementMethods(method, hashCode, callable, args);
}
return null;
}
private static Object interceptConnectionMethods(Method method, int hashCode, ConnectionInfo ci,
Callable<?> callable, Object[] args) throws Exception {
Object o = callable.call();
log.debug("connection#{} used by {}", hashCode, method.getName());
ci.setLastActiveTime(System.currentTimeMillis());
ci.setLastMethod(method.getName());
int resultHash = System.identityHashCode(o);
if (method.getName().equals("close")) {
log.info("connection#{} released", hashCode);
String stackHash = ci.getStackHash();
Integer scount = counstsByStack.get(stackHash);
if (scount != null && scount > 0) {
int newscount = scount - 1;
log.info("set connection count to {} by stack hash {}", newscount, stackHash);
if (newscount == 0) {
counstsByStack.remove(stackHash);
stacks.remove(stackHash);
} else {
counstsByStack.put(stackHash, newscount);
}
} else {
log.error("connection count by stack hash {} is not supposed to be null or less than zero", stackHash);
}
conns.remove(hashCode);
} else if (method.getName().equals("createStatement")) {
StatementExecutionInfo stmt = new StatementExecutionInfo();
stmt.setType(StatementType.NORMAL);
stmt.setHash(resultHash);
conns.get(hashCode).setCurrentStatement(stmt);
log.info("statement#{} created, type {}, attached to connection#{}", resultHash, StatementType.NORMAL, hashCode);
} else if (method.getName().equals("prepareStatement")) {
StatementExecutionInfo stmt = new StatementExecutionInfo();
stmt.setType(StatementType.PREPARED);
stmt.setSqlText((String) args[0]);
stmt.setHash(resultHash);
conns.get(hashCode).setCurrentStatement(stmt);
log.info("statement#{} created, type {}, attached to connection#{}", resultHash, StatementType.PREPARED, hashCode);
} else if (method.getName().equals("prepareCall")) {
StatementExecutionInfo stmt = new StatementExecutionInfo();
stmt.setType(StatementType.CALLABLE);
stmt.setSqlText((String) args[0]);
stmt.setHash(resultHash);
conns.get(hashCode).setCurrentStatement(stmt);
log.info("statement#{} created, type {}, attached to connection#{}", resultHash, StatementType.CALLABLE, hashCode);
}
return o;
}
private static Object interceptStatementMethods(Method method, int hashCode, Callable<?> callable, Object[] args)
throws Exception {
log.info("intercepting statement method {}", method.getName());
Object o = null;
ConnectionInfo containingCI = conns.values().stream().filter(c -> c.getCurrentStatement().getHash() == hashCode)
.findFirst().orElse(null);
if (containingCI == null) {
log.warn("unexpected situation happened: statement can't found containing connection!");
}
if (method.getName().equals("close")) {
o = callable.call();
// TODO statement close method not intercepted ??
if (containingCI != null) {
containingCI.setCurrentStatement(null);
log.info("statement#{} closed, detached from connection#{}", hashCode, containingCI.getHash());
}
}
// all statement execution method trigger
else if (method.getName().startsWith("execute")) {
String stack = getCurrentThreadStackTrace();
String stackHash = StringUtils.md5(stack);
stacks.put(stackHash, stack);
log.info("statement#{} {} started by {}", hashCode, method.getName(), stackHash);
long est = System.currentTimeMillis();
if (containingCI != null) {
containingCI.getCurrentStatement().setExecutionStartTime(est);
containingCI.getCurrentStatement().setStackHash(stackHash);
containingCI.getCurrentStatement().setExecutionCallStack(stack);
if (args.length > 0) {
containingCI.getCurrentStatement().setSqlText((String) args[0]);
}
}
Histogram.Timer timer = JDBCMetrics.SQL_EXECUTION_TIME.startTimer();
try {
o = callable.call();
} finally {
timer.observeDuration();
}
long eet = System.currentTimeMillis();
log.info("statement#{} {} finished, duration is {}", hashCode, method.getName(), (eet - est));
if (containingCI != null) {
containingCI.getCurrentStatement().setExecutionEndTime(eet);
slowStatements.add(containingCI.getCurrentStatement());
}
}
return o;
}
public static String getCurrentThreadStackTrace() throws IOException {
StringWriter sw = new StringWriter();
Throwable t = new Throwable("");
t.printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
sw.close();
return stackTrace;
}
#Advice.OnMethodExit
public static void intercept(#net.bytebuddy.asm.Advice.Origin Constructor<?> m, #This Object inst)
throws Exception {
log.debug("----------------- constructor intercept -------------------------");
if (java.sql.Connection.class.isAssignableFrom(m.getDeclaringClass())) {
// some CP library override hashCode method
int hashCode = System.identityHashCode(inst);
ConnectionInfo ci = new ConnectionInfo();
ci.setHash(hashCode);
ci.setCreationTime(System.currentTimeMillis());
String stackTrace = getCurrentThreadStackTrace();
String shash = StringUtils.md5(stackTrace);
stacks.put(shash, stackTrace);
// ci.setStack(stackTrace);
ci.setStackHash(shash);
log.info("connection#{} acquired by stack#{}", hashCode, shash);
log.debug(stackTrace);
conns.put(hashCode, ci);
Integer scount = counstsByStack.get(ci.getStackHash());
if (scount == null) {
counstsByStack.put(ci.getStackHash(), 1);
} else {
counstsByStack.put(ci.getStackHash(), scount + 1);
}
}
}
}
However, this will not work for some cases. Take HikariCP for example:
HikariCP's implementation has an abstract class ProxyConnection, which has the close method implemented, then a class HikariProxyConnection extends ProxyConnection, which overides some methods, except close. If I setup instrumentation on HikariProxyConnection, the close method will not be intercepted. If I change my code to:
new AgentBuilder.Default()
.type(startMatcher.and(isSubTypeOf(java.sql.Connection.class).and(isAbstract()))
.transform(constructorTransformer).transform(methodsTransformer).with(listener).installOn(inst);
it will work for HikariCP, but not for other connection pool implementations.
For my use case, is there a unified way? No matter what connection pool is used, and even with plain JDBC.
Your matcher:
isSubTypeOf(java.sql.Connection.class).and(not(isAbstract())
explicitly excludes abstract classes. You would need to instrument all methods to achieve what you wanted if you are using Advice.
Also, it seems like you are blending concepts:
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.This;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
The latter annotations belong to MethodDelegation, not to Advice. Refer to the javadoc to see how advice should be applied.
I am trying to extend the Dynatrace App Mon plugin to be Jenkins pipeline compatible. I have taken the source code from Github dynatrace-dashboard-2.0.5 (source code from master branch of this repository and dynatrace github repository had some issue and wasn't working, so I ended up downloading the source code of release 2.0.5)
I wrote a class DynatraceAppMonBuildEnvStep which extends AbstractStepImpl and mimics the functionality of TABuildWrapper step. I am running into issue when Utils.updateBuildVariables(build, parameters); method is called in DynatraceAppMonBuildEnvStep class, which will eventually set the environment variables. I don't get any error/exception but it is not setting the environment variables which I need to inject in the mvn build command.
When I run bat 'set' in my pipeline script, it does not show below environment variable. I am able to see these env variables if I invoke the plugin via non pipeline.
dtMarker=testservice
dtPassword=password1
dtProfile=testprofile
dtServerUrl=https://<someurl>:8021
dtTestrunID=<test id>
dtUsername=<username>
dtVersionBuild=36
dtVersionMajor=testservice
The code flow is below: DynatraceAppMonBuildEnvStep -> Utils -> DynatraceVariablesAction -> DynatraceVariablesEnvironmentContributor -> buildEnvironmentFor (method).
DynatraceAppMonBuildEnvStep.java
package com.dynatrace.jenkins.steps;
import hudson.Extension;
import hudson.model.ParameterValue;
import hudson.model.PasswordParameterValue;
import hudson.model.Run;
import hudson.model.StringParameterValue;
import hudson.model.TaskListener;
import hudson.util.FormValidation;
import jenkins.model.GlobalConfiguration;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution;
import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import com.dynatrace.jenkins.dashboard.Messages;
import com.dynatrace.jenkins.dashboard.TABuildSetupStatusAction;
import com.dynatrace.jenkins.dashboard.TAGlobalConfiguration;
import com.dynatrace.jenkins.dashboard.utils.BuildVarKeys;
import com.dynatrace.jenkins.dashboard.utils.Utils;
import com.dynatrace.sdk.server.exceptions.ServerResponseException;
import com.dynatrace.sdk.server.sessions.Sessions;
import com.dynatrace.sdk.server.sessions.models.StartRecordingRequest;
import com.dynatrace.sdk.server.testautomation.TestAutomation;
import com.dynatrace.sdk.server.testautomation.models.FetchTestRunsRequest;
import com.sun.jersey.api.client.ClientHandlerException;
import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import java.io.PrintStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.net.ssl.SSLHandshakeException;
public final class DynatraceAppMonBuildEnvStep extends AbstractStepImpl {
/**
* The 1st arg is system profile name, the 2nd is build number
*/
private static final String RECORD_SESSION_NAME = "%s_Jenkins_build_%s";
public final String systemProfile;
// Test run attributes - no versionBuild attribute because it's taken from
// the build object
public final String versionMajor;
public final String versionMinor;
public final String versionRevision;
public final String versionMilestone;
public final String marker;
public final Boolean recordSession;
#DataBoundConstructor
public DynatraceAppMonBuildEnvStep(final String systemProfile, final String versionMajor, final String versionMinor,
final String versionRevision, final String versionMilestone, final String marker,
final Boolean recordSession) {
this.systemProfile = systemProfile;
this.versionMajor = versionMajor;
this.versionMinor = versionMinor;
this.versionRevision = versionRevision;
this.versionMilestone = versionMilestone;
this.marker = marker;
this.recordSession = recordSession;
}
private void setupBuildVariables(Run<?, ?> build, String serverUrl) {
final TAGlobalConfiguration globalConfig = GlobalConfiguration.all().get(TAGlobalConfiguration.class);
List<ParameterValue> parameters = new ArrayList<>(10);
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_SYSTEM_PROFILE, systemProfile));
if (StringUtils.isNotEmpty(versionMajor)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_VERSION_MAJOR, versionMajor));
}
if (StringUtils.isNotEmpty(versionMinor)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_VERSION_MINOR, versionMinor));
}
if (StringUtils.isNotEmpty(versionRevision)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_VERSION_REVISION, versionRevision));
}
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_VERSION_BUILD,
Integer.toString(build.getNumber())));
if (StringUtils.isNotEmpty(versionMilestone)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_VERSION_MILESTONE, versionMilestone));
}
if (StringUtils.isNotEmpty(marker)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_MARKER, marker));
}
if (StringUtils.isNotEmpty(serverUrl)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_GLOBAL_SERVER_URL, serverUrl));
}
if (StringUtils.isNotEmpty(globalConfig.username)) {
parameters.add(new StringParameterValue(BuildVarKeys.BUILD_VAR_KEY_GLOBAL_USERNAME, globalConfig.username));
}
if (StringUtils.isNotEmpty(globalConfig.password)) {
parameters
.add(new PasswordParameterValue(BuildVarKeys.BUILD_VAR_KEY_GLOBAL_PASSWORD, globalConfig.password));
}
System.out.println("first call to utlis.updateBuildVariables from step 1::::");
Utils.updateBuildVariables(build, parameters);
}
#Extension
public static final class DescriptorImpl extends AbstractStepDescriptorImpl {
public DescriptorImpl() {
super(Execution.class);
}
#Override
public String getFunctionName() {
return "dynatraceAppMonBuildEnvStep";
}
private static final boolean DEFAULT_RECORD_SESSION = false;
public static boolean getDefaultRecordSession() {
return DEFAULT_RECORD_SESSION;
}
#Nonnull
#Override
public String getDisplayName() {
return "Use Dynatrace AppMon to monitor tests";
}
public FormValidation doCheckSystemProfile(#QueryParameter final String systemProfile) {
if (StringUtils.isNotBlank(systemProfile)) {
return FormValidation.ok();
} else {
return FormValidation.error(Messages.RECORDER_VALIDATION_BLANK_SYSTEM_PROFILE());
}
}
public FormValidation doTestDynatraceConnection(#QueryParameter final String systemProfile) {
try {
final TestAutomation connection = new TestAutomation(Utils.createClient());
FetchTestRunsRequest request = new FetchTestRunsRequest(systemProfile);
// We set many constraints to ENSURE no or few testruns are
// returned as this is testing the connection only
request.setVersionBuildFilter("1024");
request.setVersionMajorFilter("1024");
request.setMaxBuilds(1);
try {
connection.fetchTestRuns(request);
} catch (ServerResponseException e) {
switch (e.getStatusCode()) {
case HTTP_UNAUTHORIZED:
return FormValidation.warning(Messages.RECORDER_VALIDATION_CONNECTION_UNAUTHORIZED());
case HTTP_FORBIDDEN:
return FormValidation.warning(Messages.RECORDER_VALIDATION_CONNECTION_FORBIDDEN());
case HTTP_NOT_FOUND:
return FormValidation.warning(Messages.RECORDER_VALIDATION_CONNECTION_NOT_FOUND());
default:
return FormValidation
.warning(Messages.RECORDER_VALIDATION_CONNECTION_OTHER_CODE(e.getStatusCode()));
}
}
return FormValidation.ok(Messages.RECORDER_VALIDATION_CONNECTION_OK());
} catch (Exception e) {
e.printStackTrace();
if (e.getCause() instanceof ClientHandlerException
&& e.getCause().getCause() instanceof SSLHandshakeException) {
return FormValidation.warning(Messages.RECORDER_VALIDATION_CONNECTION_CERT_EXCEPTION(e.toString()));
}
return FormValidation.warning(Messages.RECORDER_VALIDATION_CONNECTION_UNKNOWN(e.toString()));
}
}
}
public static final class Execution extends AbstractSynchronousNonBlockingStepExecution<Boolean> {
#Inject
private transient DynatraceAppMonBuildEnvStep step;
// public final Boolean recordSession = step.recordSession;
// public final Boolean recordSession = false;
#StepContextParameter
private transient TaskListener listener;
#StepContextParameter
private transient Run<?, ?> build;
#Override
protected Boolean run() throws Exception {
Boolean result = true;
final TAGlobalConfiguration globalConfig = GlobalConfiguration.all().get(TAGlobalConfiguration.class);
final Sessions sessions = new Sessions(Utils.createClient());
final PrintStream logger = listener.getLogger();
// logger.println("host is:"+globalConfig.host);
try {
String serverUrl = new URI(globalConfig.protocol, null, globalConfig.host, globalConfig.port, null,
null, null).toString();
if (step.recordSession) {
logger.println("Starting session recording via Dynatrace Server REST interface...");
StartRecordingRequest request = new StartRecordingRequest(step.systemProfile);
request.setPresentableName(
String.format(RECORD_SESSION_NAME, step.systemProfile, build.getNumber()));
final String sessionNameOut = sessions.startRecording(request);
logger.println("Dynatrace session " + sessionNameOut + " has been started");
}
step.setupBuildVariables(build, serverUrl);
} catch (Exception e) {
e.printStackTrace();
build.addAction(new TABuildSetupStatusAction(true));
logger.println(
"ERROR: Dynatrace AppMon Plugin - build set up failed (see the stacktrace to get more information):\n"
+ e.toString());
}
// final PrintStream logger = listener.getLogger();
/*
* logger.println("Dynatrace AppMon Plugin - build tear down...");
* try { if (recordSession) { final String storedSessionName =
* storeSession(logger); Utils.updateBuildVariable(build,
* BuildVarKeys.BUILD_VAR_KEY_STORED_SESSION_NAME,
* storedSessionName); } } catch (Exception e) {
* e.printStackTrace(); logger.
* println("ERROR: Dynatrace AppMon Plugin - build tear down failed (see the stacktrace to get more information):\n"
* + e.toString()); }
*/
return result;
}
private static final long serialVersionUID = 1L;
/**
* #return stored session name
*/
/*
* private String storeSession(final PrintStream logger) throws
* ServerResponseException, ServerConnectionException { logger.
* println("Storing session via Dynatrace Server REST interface...");
* String sessionName = sessions.stopRecording(step.systemProfile);
* logger.println("Dynatrace session " + sessionName +
* " has been stored"); return sessionName; }
*/
}
}
**Utils.java**
package com.dynatrace.jenkins.dashboard.utils;
import com.dynatrace.jenkins.dashboard.TABuildSetupStatusAction;
import com.dynatrace.jenkins.dashboard.TAGlobalConfiguration;
import com.dynatrace.jenkins.dashboard.model_2_0_0.*;
import com.dynatrace.sdk.server.BasicServerConfiguration;
import com.dynatrace.sdk.server.DynatraceClient;
import com.dynatrace.sdk.server.testautomation.models.TestRuns;
import hudson.model.AbstractBuild;
import hudson.model.ParameterValue;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.StringParameterValue;
import jenkins.model.GlobalConfiguration;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.util.*;
/**
* Created by krzysztof.necel on 2016-01-25.
*/
public final class Utils {
public static final String TEST_MEASURE_UNIT_DEFAULT = "num";
public static final String DYNATRACE_ICON_24_X_24_FILEPATH = "/plugin/dynatrace-dashboard/images/dynatrace_icon_24x24.png";
public static final String DYNATRACE_ICON_48_X_48_FILEPATH = "/plugin/dynatrace-dashboard/images/dynatrace_icon_48x48.png";
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
private static final String FORMAT_DOUBLE_NULL_VALUE = "N/A";
private Utils() {
}
public static DynatraceClient createClient() {
final TAGlobalConfiguration globalConfig = GlobalConfiguration.all().get(TAGlobalConfiguration.class);
BasicServerConfiguration config = new BasicServerConfiguration(globalConfig.username,
globalConfig.password,
globalConfig.protocol.startsWith("https"),
globalConfig.host,
globalConfig.port,
globalConfig.validateCerts,
//connection timeout, 0 stands for infinite
0);
return new DynatraceClient(config);
}
public static TAReportDetails convertTestRuns(TestRuns sdkTestRuns) {
ArrayList<TestRun> testRuns = new ArrayList<>();
if (sdkTestRuns != null) {
for (com.dynatrace.sdk.server.testautomation.models.TestRun tr : sdkTestRuns.getTestRuns()) {
testRuns.add(convertTestRun(tr));
}
}
return new TAReportDetails(testRuns);
}
public static TestRun convertTestRun(com.dynatrace.sdk.server.testautomation.models.TestRun sdkTestRun) {
List<TestResult> testResults = new ArrayList<>();
for (com.dynatrace.sdk.server.testautomation.models.TestResult sdkResult : sdkTestRun.getTestResults()) {
testResults.add(convertTestResult(sdkResult));
}
Map<TestStatus, Integer> testRunSummary = new EnumMap<>(TestStatus.class);
testRunSummary.put(TestStatus.FAILED, sdkTestRun.getFailedCount());
testRunSummary.put(TestStatus.DEGRADED, sdkTestRun.getDegradedCount());
testRunSummary.put(TestStatus.VOLATILE, sdkTestRun.getVolatileCount());
testRunSummary.put(TestStatus.IMPROVED, sdkTestRun.getImprovedCount());
testRunSummary.put(TestStatus.PASSED, sdkTestRun.getPassedCount());
return new TestRun(testResults, testRunSummary, sdkTestRun.getId(), convertTestCategory(sdkTestRun.getCategory()));
}
public static TestResult convertTestResult(com.dynatrace.sdk.server.testautomation.models.TestResult sdkTestResult) {
Set<TestMeasure> measures = new HashSet<>();
for (com.dynatrace.sdk.server.testautomation.models.TestMeasure sdkMeasure : sdkTestResult.getMeasures()) {
measures.add(convertTestMeasure(sdkMeasure));
}
return new TestResult(new Date(sdkTestResult.getExecutionTime()), sdkTestResult.getName(), sdkTestResult.getPackageName(), sdkTestResult.getPlatform(), convertTestStatus(sdkTestResult.getStatus()), measures);
}
public static TestMeasure convertTestMeasure(com.dynatrace.sdk.server.testautomation.models.TestMeasure sdkTestMeasure) {
String unit = sdkTestMeasure.getUnit() != null ? sdkTestMeasure.getUnit() : TEST_MEASURE_UNIT_DEFAULT;
return new TestMeasure(sdkTestMeasure.getName(),
sdkTestMeasure.getMetricGroup(),
sdkTestMeasure.getExpectedMin(),
sdkTestMeasure.getExpectedMax(),
sdkTestMeasure.getValue(),
unit,
sdkTestMeasure.getViolationPercentage());
}
public static TestCategory convertTestCategory(com.dynatrace.sdk.server.testautomation.models.TestCategory sdkTestCategory) {
switch (sdkTestCategory) {
case UNIT:
return TestCategory.UNIT;
case UI_DRIVEN:
return TestCategory.UI_DRIVEN;
case WEB_API:
return TestCategory.WEB_API;
case PERFORMANCE:
return TestCategory.PERFORMANCE;
}
throw new IllegalArgumentException("Could not convert TestCategory");
}
public static TestStatus convertTestStatus(com.dynatrace.sdk.server.testautomation.models.TestStatus sdkTestStatus) {
return TestStatus.valueOf(sdkTestStatus.name());
}
public static Map<TestStatus, Integer> createReportAggregatedSummary(TAReportDetails reportDetails) {
// just sum all the reports for test runs
final Map<TestStatus, Integer> summary = new EnumMap<>(TestStatus.class);
for (TestRun testRun : reportDetails.getTestRuns()) {
Map<TestStatus, Integer> testRunSummary = testRun.getSummary();
for (Map.Entry<TestStatus, Integer> entry : testRunSummary.entrySet()) {
Integer value = summary.get(entry.getKey());
summary.put(entry.getKey(), value == null ? entry.getValue() : entry.getValue() + value);
}
}
return summary;
}
public static String formatDouble(Double d) {
return d == null ? FORMAT_DOUBLE_NULL_VALUE : DECIMAL_FORMAT.format(d);
}
public static String formatDoublePercentage(Double d) {
return d == null ? FORMAT_DOUBLE_NULL_VALUE : DECIMAL_FORMAT.format(d * 100);
}
public static boolean isValidBuild(AbstractBuild build, PrintStream logger, String message) {
if (build.getResult() == Result.ABORTED) {
logger.println("Build has been aborted - " + message);
return false;
}
TABuildSetupStatusAction setupStatusAction = build.getAction(TABuildSetupStatusAction.class);
if (setupStatusAction != null && setupStatusAction.isSetupFailed()) {
logger.println("Failed to set up environment for Dynatrace AppMon Plugin - " + message);
return false;
}
return true;
}
public static boolean isValidBuild(Run build, PrintStream logger, String message) {
if (build.getResult() == Result.ABORTED) {
logger.println("Build has been aborted - " + message);
return false;
}
TABuildSetupStatusAction setupStatusAction = build.getAction(TABuildSetupStatusAction.class);
if (setupStatusAction != null && setupStatusAction.isSetupFailed()) {
logger.println("Failed to set up environment for Dynatrace AppMon Plugin - " + message);
return false;
}
return true;
}
public static void updateBuildVariables(AbstractBuild<?, ?> build, List<ParameterValue> parameters) {
DynatraceVariablesAction existingAction = build.getAction(DynatraceVariablesAction.class);
if (existingAction == null) {
build.addAction(new DynatraceVariablesAction(parameters));
} else {
build.replaceAction(existingAction.createUpdated(parameters));
}
}
public static void updateBuildVariables(Run<?, ?> build, List<ParameterValue> parameters) {
DynatraceVariablesAction existingAction = build.getAction(DynatraceVariablesAction.class);
if (existingAction == null) {
build.addAction(new DynatraceVariablesAction(parameters));
} else {
build.replaceAction(existingAction.createUpdated(parameters));
}
}
public static void updateBuildVariable(AbstractBuild<?, ?> build, String key, String value) {
updateBuildVariables(build, Collections.<ParameterValue>singletonList(new StringParameterValue(key, value)));
}
public static void updateBuildVariable(Run<?, ?> build, String key, String value) {
updateBuildVariables(build, Collections.<ParameterValue>singletonList(new StringParameterValue(key, value)));
}
}
**DynatraceVariablesAction.java**
package com.dynatrace.jenkins.dashboard.utils;
import hudson.EnvVars;
import hudson.Extension;
import hudson.model.*;
import javax.annotation.Nonnull;
import java.util.*;
public class DynatraceVariablesAction extends ParametersAction {
private List<ParameterValue> parameters = new ArrayList<>();
public DynatraceVariablesAction(Collection<? extends ParameterValue> parameters) {
this.parameters.addAll(parameters);
}
#Override
public List<ParameterValue> getParameters() {
return Collections.unmodifiableList(parameters);
}
#Override
public ParameterValue getParameter(String name) {
for (ParameterValue p : parameters) {
if (p == null) continue;
if (p.getName().equals(name))
return p;
}
return null;
}
#Nonnull
#Override
public DynatraceVariablesAction createUpdated(Collection<? extends ParameterValue> overrides) {
List<ParameterValue> newParams = new ArrayList<>(overrides);
outer:
for (ParameterValue value : this.parameters) {
for (ParameterValue newParam : newParams) {
if (newParam.getName().equals(value.getName())) {
continue outer;
}
}
newParams.add(value);
}
return new DynatraceVariablesAction(newParams);
}
#Extension
public static final class DynatraceBuildVariablesContributor extends BuildVariableContributor {
#Override
public void buildVariablesFor(AbstractBuild r, Map<String, String> variables) {
DynatraceVariablesAction a = r.getAction(DynatraceVariablesAction.class);
if (a == null) {
return;
}
for (ParameterValue spv : a.getParameters()) {
variables.put(spv.getName(), String.valueOf(spv.getValue()));
}
}
}
#Extension
public static final class DynatraceVariablesEnvironmentContributor extends EnvironmentContributor {
#Override
public void buildEnvironmentFor(Run r, EnvVars vars, TaskListener listener) {
DynatraceVariablesAction a = r.getAction(DynatraceVariablesAction.class);
if (a == null) {
return;
}
for (ParameterValue spv : a.getParameters()) {
vars.put(spv.getName(), String.valueOf(spv.getValue()));
}
}
}
}
I also tried to set the environment variables by extending InvisibleAction class instead of ParametersAction, as performance-signature-dynatrace-plugin is doing but that didn't seem to work as well. Dynatrace performance signature plugin is setting the environment variables in a bit different way. See these two links:
[https://github.com/jenkinsci/performance-signature-dynatrace-plugin/blob/master/dynatrace/src/main/java/de/tsystems/mms/apm/performancesignature/dynatrace/PerfSigEnvInvisAction.java][1]
[https://github.com/jenkinsci/performance-signature-dynatrace-plugin/blob/master/dynatrace/src/main/java/de/tsystems/mms/apm/performancesignature/dynatrace/PerfSigEnvContributor.java][2]
[1]: https://github.com/jenkinsci/performance-signature-dynatrace-plugin/blob/master/dynatrace/src/main/java/de/tsystems/mms/apm/performancesignature/dynatrace/PerfSigEnvInvisAction.java
[2]: https://github.com/jenkinsci/performance-signature-dynatrace-plugin/blob/master/dynatrace/src/main/java/de/tsystems/mms/apm/performancesignature/dynatrace/PerfSigEnvContributor.java
Any help would be highly appreciated. I hope I was able to describe the problem. Please feel free to comment if my issue/question is not clear.
Thanks.
Here, the request Param string is :
firstName=jack&lastName=lily&gender=1&foods=Steak&foods=Pizza"e=Enter+your+favorite+quote!&education=Jr.High&tOfD=Day
And Mapped class is :
public class Student {
private String firstName;
private String lastName;
private Integer gender;
private List<String> foods;
private String quote;
private String education;
private String tOfD;
getXxx()....;
setXxx()....;
}
And Now, I want to write a generic util class to convert the string to a bean.
public final class InjectUtil<T> {
private static final Logger LOGGER = LoggerFactory.getLogger(InjectUtil.class);
public static <T> T converter2Obj(String source, Class<T> tClass) {
T t = null;
try {
t = tClass.newInstance();
if(source != null && source.length() > 0) {
String[] fields = source.split("&");
for(String field : fields) {
String[] fieldKeyValue = field.split("\\=");
String fieldKey = fieldKeyValue[0];
String fieldValue = fieldKeyValue[1];
// help
}
}
} catch(InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return t;
}
}
take care of the help, how can i use BeanUtils converter the "foods=Steak&foods=Pizza" to the List attribute.
Here is a way of doing it :
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
public final class InjectUtil<T> {
// private static final Logger LOGGER =
// LoggerFactory.getLogger(InjectUtil.class);
public static <T> T converter2Obj(String source, Class<T> tClass) {
T t = null;
try {
t = tClass.newInstance();
Map<String, Object> params = new HashMap<String, Object>();
if (source != null && source.length() > 0) {
String[] fields = source.split("&");
for (String field : fields) {
String[] fieldKeyValue = field.split("\\=");
String fieldKey = fieldKeyValue[0];
String fieldValue = fieldKeyValue[1];
if (params.containsKey(fieldKey)) {
//the key does not exist as yet
Object keyValueRetrieved = params.get(fieldKey);
if (keyValueRetrieved instanceof String) {
//key exists , it is single value that has been added now.
//change that now to a list to add more values
ArrayList<String> values = new ArrayList<String>();
values.add(keyValueRetrieved.toString());
values.add(fieldValue);
params.put(fieldKey, values);
} else {
//key exists , it is a list already. Add more values
((ArrayList<String>) keyValueRetrieved).add(fieldValue);
}
} else {
params.put(fieldKey, fieldValue);
}
}
}
BeanUtils.populate(t, params);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("--------------------------------------------");
System.out.println(t.toString());
System.out.println("--------------------------------------------");
return t;
}
}
There are optimizations you can do , hopefully this gives you an idea
You can use as follows, you need to populate foodList (with values as [Steak,Pizza]) and then set to the bean using following method.
PropertyUtils.setProperty(studentBean, "foods", foodList);
or
BeanUtils.setProperty(studentBean, "foods", foodList);
This code:
#Override
public List<FactCodeDto> getAllFactsWithoutParentsAsFactDto() {
String completeQuery = FactCodeQueries.SELECT_DTO_FROM_FACT_WITH_NO_PARENTS;
Query query = createHibernateQueryForUnmappedTypeFactDto(completeQuery);
List<FactCodeDto> factDtoList = query.list(); //line 133
return factDtoList;
}
calling this method:
private Query createHibernateQueryForUnmappedTypeFactDto(String sqlQuery) throws HibernateException {
return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(Transformers.aliasToBean(FactCodeDto.class));
}
gives me a ClassCastException -> part of the trace:
Caused by: java.lang.ClassCastException: org.bamboomy.cjr.dto.FactCodeDto cannot be cast to java.util.Map
at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)
at org.hibernate.transform.AliasToBeanResultTransformer.transformTuple(AliasToBeanResultTransformer.java:78)
at org.hibernate.hql.internal.HolderInstantiator.instantiate(HolderInstantiator.java:75)
at org.hibernate.loader.custom.CustomLoader.getResultList(CustomLoader.java:435)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423)
at org.hibernate.loader.Loader.list(Loader.java:2418)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:336)
at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:1898)
at org.hibernate.internal.AbstractSessionImpl.list(AbstractSessionImpl.java:318)
at org.hibernate.internal.SQLQueryImpl.list(SQLQueryImpl.java:125)
at org.bamboomy.cjr.dao.factcode.FactCodeDAOImpl.getAllFactsWithoutParentsAsFactDto(FactCodeDAOImpl.java:133)
Which is pretty strange because, indeed, if you look up the source code of Hibernate it tries to do this:
#Override
#SuppressWarnings("unchecked")
public void set(Object target, Object value, SessionFactoryImplementor factory) {
( (Map) target ).put( propertyName, value ); //line 102
}
Which doesn't make any sense...
target is of type Class and this code tries to cast it to Map,
why does it try to do that???
any pointers are more than welcome...
I'm using Hibernate 5 (and am upgrading from 3)...
edit: I also use Spring (4.2.1.RELEASE; also upgrading) which calls these methods upon deploy, any debugging pointers are most welcome as well...
edit 2: (the whole FactCodeDto class, as requested)
package org.bamboomy.cjr.dto;
import org.bamboomy.cjr.model.FactCode;
import org.bamboomy.cjr.model.FactCodeType;
import org.bamboomy.cjr.utility.FullDateUtil;
import org.bamboomy.cjr.utility.Locales;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.util.Assert;
import java.util.*;
#Getter
#Setter
#ToString
public class FactCodeDto extends TreeNodeValue {
private String cdFact;
private String cdFactSuffix;
private Boolean isSupplementCode;
private Boolean isTitleCode;
private Boolean mustBeFollowed;
private Date activeFrom;
private Date activeTo;
private Boolean isCode;
private Long idFact;
private Long idParent;
private String type;
Map<Locale, String> description = new HashMap<Locale, String>(3);
public FactCodeDto() {
}
public FactCodeDto(String prefix, String suffix) {
super();
this.cdFact = prefix;
this.cdFactSuffix = suffix;
}
public FactCodeDto(String cdFact, String cdFactSuffix, Boolean isSupplementCode, Boolean mustBeFollowed) {
super();
this.cdFact = cdFact;
this.cdFactSuffix = cdFactSuffix;
this.isSupplementCode = isSupplementCode;
this.mustBeFollowed = mustBeFollowed;
}
public FactCodeDto(String cdFact, String cdFactSuffix, Boolean isSupplementCode, Boolean mustBeFollowed, Long idFact, Long idParent, Boolean isCode, Boolean isTitleCode, Date from, Date to, Map<Locale, String> descriptions,String type) {
super();
this.cdFact = cdFact;
this.cdFactSuffix = cdFactSuffix;
this.isSupplementCode = isSupplementCode;
this.mustBeFollowed = mustBeFollowed;
this.idFact = idFact;
this.idParent = idParent;
this.isCode = isCode;
this.isTitleCode = isTitleCode;
this.activeFrom = from;
this.activeTo = to;
if (descriptions != null) {
this.description = descriptions;
}
this.type = type;
}
public FactCodeDto(FactCode fc) {
this(fc.getPrefix(), fc.getSuffix(), fc.isSupplementCode(), fc.isHasMandatorySupplCodes(), fc.getId(), fc.getParent(), fc.isActualCode(), fc.isTitleCode(), fc.getActiveFrom(), fc.getActiveTo(), fc.getAllDesc(),fc.getType().getCode());
}
public String formatCode() {
return FactCode.formatCode(cdFact, cdFactSuffix);
}
public boolean isActive() {
Date now = new Date(System.currentTimeMillis());
return FullDateUtil.isBetweenDates(now, this.activeFrom, this.activeTo);
}
public void setDescFr(String s) {
description.put(Locales.FRENCH, s);
}
public void setDescNl(String s) {
description.put(Locales.DUTCH, s);
}
public void setDescDe(String s) {
description.put(Locales.GERMAN, s);
}
/**
* public String toString() {
* StringBuilder sb = new StringBuilder();
* sb.append(getIdFact() + ": ")
* .append(getIdParent() + ": ")
* .append(" " + cdFact + cdFactSuffix + ": " + (isSupplementCode ? "NO Principal " : " Principal "))
* .append((mustBeFollowed ? " Must Be Followed " : "NOT Must Be Followed "));
* return sb.toString();
* }
*/
public Map<Locale, String> getDescription() {
return description;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
String fullCode = formatCode();
result = prime * result + ((fullCode == null) ? 0 : fullCode.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
FactCodeDto other = (FactCodeDto) obj;
return formatCode().equals(other.formatCode());
}
#Override
public boolean isChildOf(TreeNodeValue value) {
Assert.notNull(value);
boolean isChild = false;
if (value instanceof FactCodeDto) {
if (this.getIdParent() != null) {
isChild = this.getIdParent().equals(((FactCodeDto) value).getIdFact());
}
}
return isChild;
}
#Override
public boolean isBrotherOf(TreeNodeValue value) {
Assert.notNull(value);
boolean isBrother = false;
if (value instanceof FactCodeDto) {
if (this.getIdParent() != null) {
isBrother = this.getIdParent().equals(((FactCodeDto) value).getIdParent());
}
}
return isBrother;
}
#Override
public boolean isParentOf(TreeNodeValue value) {
Assert.notNull(value);
boolean isParent = false;
if (value instanceof FactCodeDto) {
isParent = this.getIdFact().equals(((FactCodeDto) value).getIdParent());
}
return isParent;
}
#Override
public int compareTo(TreeNodeValue to) {
if (to instanceof FactCodeDto) {
return formatCode().compareTo(((FactCodeDto) to).formatCode());
} else return 1;
}
public String getCode() {
return formatCode();
}
}
I found that AliasToBean has changed in Hibernate 5. For me adding getter for my field fixed the problem.
This exception occurs when the setters and getters are not mapped correctly to the column names.
Make sure you have the correct getters and setters for the query(Correct names and correct datatypes).
Read more about it here:
http://javahonk.com/java-lang-classcastexception-com-wfs-otc-datamodels-imagineexpirymodel-cannot-cast-java-util-map/
I do some investigation on this question. The problem is that Hibernate converts aliases for column names to upper case — cdFact becomesCDFACT.
Read for a more deeply explanation and workaround here:
mapping Hibernate query results to custom class?
In the end it wasn't so hard to find a solution,
I just created my own (custom) ResultTransformer and specified that in the setResultTransformer method:
private Query createHibernateQueryForUnmappedTypeFactDto(String sqlQuery) throws HibernateException {
return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(new FactCodeDtoResultTransformer());
//return FactCodeQueries.addScalars(createSQLQuery(sqlQuery)).setResultTransformer(Transformers.aliasToBean(FactCodeDto.class));
}
the code of the custom result transformer:
package org.bamboomy.cjr.dao.factcode;
import org.bamboomy.cjr.dto.FactCodeDto;
import java.util.Date;
import java.util.List;
/**
* Created by a162299 on 3-11-2015.
*/
public class FactCodeDtoResultTransformer implements org.hibernate.transform.ResultTransformer {
#Override
public Object transformTuple(Object[] objects, String[] strings) {
FactCodeDto result = new FactCodeDto();
for (int i = 0; i < objects.length; i++) {
setField(result, strings[i], objects[i]);
}
return result;
}
private void setField(FactCodeDto result, String string, Object object) {
if (string.equalsIgnoreCase("cdFact")) {
result.setCdFact((String) object);
} else if (string.equalsIgnoreCase("cdFactSuffix")) {
result.setCdFactSuffix((String) object);
} else if (string.equalsIgnoreCase("isSupplementCode")) {
result.setIsSupplementCode((Boolean) object);
} else if (string.equalsIgnoreCase("isTitleCode")) {
result.setIsTitleCode((Boolean) object);
} else if (string.equalsIgnoreCase("mustBeFollowed")) {
result.setMustBeFollowed((Boolean) object);
} else if (string.equalsIgnoreCase("activeFrom")) {
result.setActiveFrom((Date) object);
} else if (string.equalsIgnoreCase("activeTo")) {
result.setActiveTo((Date) object);
} else if (string.equalsIgnoreCase("descFr")) {
result.setDescFr((String) object);
} else if (string.equalsIgnoreCase("descNl")) {
result.setDescNl((String) object);
} else if (string.equalsIgnoreCase("descDe")) {
result.setDescDe((String) object);
} else if (string.equalsIgnoreCase("type")) {
result.setType((String) object);
} else if (string.equalsIgnoreCase("idFact")) {
result.setIdFact((Long) object);
} else if (string.equalsIgnoreCase("idParent")) {
result.setIdParent((Long) object);
} else if (string.equalsIgnoreCase("isCode")) {
result.setIsCode((Boolean) object);
} else {
throw new RuntimeException("unknown field");
}
}
#Override
public List transformList(List list) {
return list;
}
}
in hibernate 3 you could set Aliasses to queries but you can't do that anymore in hibernate 5 (correct me if I'm wrong) hence the aliasToBean is something you only can use when actually using aliasses; which I didn't, hence the exception.
Im my case :
=> write sql query and try to map result to Class List
=> Use "Transformers.aliasToBean"
=> get Error "cannot be cast to java.util.Map"
Solution :
=> just put \" before and after query aliases
ex:
"select first_name as \"firstName\" from test"
The problem is that Hibernate converts aliases for column names to upper case or lower case
I solved it by defining my own custom transformer as given below -
import org.hibernate.transform.BasicTransformerAdapter;
public class FluentHibernateResultTransformer extends BasicTransformerAdapter {
private static final long serialVersionUID = 6825154815776629666L;
private final Class<?> resultClass;
private NestedSetter[] setters;
public FluentHibernateResultTransformer(Class<?> resultClass) {
this.resultClass = resultClass;
}
#Override
public Object transformTuple(Object[] tuple, String[] aliases) {
createCachedSetters(resultClass, aliases);
Object result = ClassUtils.newInstance(resultClass);
for (int i = 0; i < aliases.length; i++) {
setters[i].set(result, tuple[i]);
}
return result;
}
private void createCachedSetters(Class<?> resultClass, String[] aliases) {
if (setters == null) {
setters = createSetters(resultClass, aliases);
}
}
private static NestedSetter[] createSetters(Class<?> resultClass, String[] aliases) {
NestedSetter[] result = new NestedSetter[aliases.length];
for (int i = 0; i < aliases.length; i++) {
result[i] = NestedSetter.create(resultClass, aliases[i]);
}
return result;
}
}
And used this way inside the repository method -
#Override
public List<WalletVO> getWalletRelatedData(WalletRequest walletRequest,
Set<String> requiredVariablesSet) throws GenericBusinessException {
String query = getWalletQuery(requiredVariablesSet);
try {
if (query != null && !query.isEmpty()) {
SQLQuery sqlQuery = mEntityManager.unwrap(Session.class).createSQLQuery(query);
return sqlQuery.setResultTransformer(new FluentHibernateResultTransformer(WalletVO.class))
.list();
}
} catch (Exception ex) {
exceptionThrower.throwDatabaseException(null, false);
}
return Collections.emptyList();
}
It worked perfectly !!!
Try putting Column names and field names both in capital letters.
This exception occurs when the class that you specified in the AliasToBeanResultTransformer does not have getter for the corresponding columns. Although the exception details from the hibernate are misleading.
Here's my code:
public String generateEISReports_PDF(){
surveyReportService.setSurveyReportDA(surveyReportDA);
surveyReportList = surveyReportService.getSurveyReport(surveyType, surveyDate, projectCode, employeeCode);
if(surveyReportList != null){
System.out.println(surveyReportList + "testing");
System.out.println(surveyReportList.size() + "size ito");
for (SurveyReport surveyReport : surveyReportList) {
System.out.println(surveyReport.getRiskRank().toString() + "asdf");
surveyReports.add(surveyReport);
}
}
this.compileTheJasperReports();
return SUCCESS;
}
I am getting the whole row values with this code as an object. I want to iterate the field values in every list of objects. How can I do that?
By using reflection you can achieve that. Following is the code. This might help you.
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class SurveyReport {
public int localServeryCont; // if you make it private then changes have to be done in 'SurveyIterator' inner class.
public String surveyReporterName;
public static void main(String[] args) {
List<SurveyReport> surveyReportList = new ArrayList<SurveyReport>();
SurveyReport sr = new SurveyReport(); //first object creation
sr.localServeryCont = 10;
sr.surveyReporterName = "AAA";
surveyReportList.add(sr);
sr = new SurveyReport(); //second object creation
sr.localServeryCont = 100;
sr.surveyReporterName = "BBB";
surveyReportList.add(sr); //two objects are in the list-object.
for (SurveyReport surveyReport : surveyReportList) {
Iterator<String> itr = surveyReport.iterator(); //You can work around with 'java.lang.Iterable' to use 'foreach' loop
while (itr.hasNext()) { //this is what you might be expecting
System.out.println("SurveyReport's object's values : " + itr.next());
}
}
}
public Iterator<String> iterator() { //here is method to get iterator object.
return new SurveyIterator();
}
private class SurveyIterator implements Iterator<String> { //creating 'SurveyIterator' INNER class
private int totalAvailableField = SurveyReport.class.getDeclaredFields().length;
int cursor = 0;
Field[] surveyReportFields = SurveyReport.class.getFields();
#Override
public boolean hasNext() {
return cursor != totalAvailableField;
}
#Override
public String next() {
String next = null;
try {
next = (surveyReportFields[cursor].get(SurveyReport.this)).toString();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
cursor++;
return next;
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}