Avoiding If statement to check if object is Null [duplicate] - spring

This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 3 years ago.
I'm using Lombok S1F4j to log my data and In order to avoid logging empty data , I check if the object is null or not . I want avoid this guys so my code is more robuste and so easy to test .
This is an example :
if (object != null)
{
log.info("lalalalal", object)
object1.set(object) }
Is there anyway to avoid checking null and not logging if object is null ?

You can create a wrapper function something like:
public static void log_info(Logger logger, Object obj) {
if (obj != null) {
logger.info(obj);
}
}
And, use this wrapper method in place of logging methods.

you can add a question mark before calling any functions or data fields of an object. That will only call the function if the object is not null
object?.function()

Related

Spring-AOP Return value of Aspect #AfterReturn is not working

#AfterReturning(value = "anyPublicMethod() && applyPrivacy()", returning = "result")
public Object afterReturning(JoinPoint joinPoint, Object result) {
return someService.createNewObjectWithHelpOfResult(result);
}
My intention was to fill some null values in result fields. So in method createNewObjectWithHelpOfResult I'm creating a new Object and setting only the required values. But return value is not reflecting after afterReturning method is finished. But if I do mutations on result. They're very well reflected after aspect #AfterReturning method ends, but I want the return value to be used? Is this not possible? I'll have to do mutation only?
What #M.Deinum explained, is documented in the Spring manual, section "After Returning Advice". The end of the section reads:
Please note that it is not possible to return a totally different reference when using after returning advice.
Therefore, you cannot just make your #AfterReturning advice have a return type other than void and hope it will magically return something. As the advice type name implies, all 3 types of #After* advices run after the method has returned already. There is nothing you can do to change the result (except for altering internal state of an object instance). You can merely read (and e.g. log) it.
The solution, like #M.Deinum said, is an #Around advice, see also again the Spring manual.
It is generally a good idea to at least study the manual and learn some basics or take a look at examples before asking questions in public. I am sure you did not find any valid example for an #After* advice with non-void return type.
I am using #AfterReturning on the methods whose return type is String but instead of String I am getting null as result
#AfterReturning(value = "execution(* com.example.demo.aop.business..(..))", returning = "result")
public void afterA(JoinPoint joinPoint, Object result) {
log.info("After method {} returned with value {}", joinPoint, result);
}
O/P - After method execution(void com.example.demo.aop.business.Business2.disp()) returned with value null

Why isEmpty () not null checked?

First, ask for your understanding that English is not fluent.
I am currently implementing an upload function using MultipartFile. It is checking for an empty value with isEmpty() in case there is no file. When i submit without selecting a file, a NullPointerException occurs in the isEmpty () part.
So, when i do not have a file, it works fine if i check file != null instead of isEmpty(). Looking at the implementation of MultipartFile(ex:CommonsMultipartFile, StandardMultipartFile...), this only check if the file size is zero. If so, I wonder if it is OK to check it like file != null to check for null.
if(uploadFile.isEmpty()){ //Here a NullPointerException is thrown
...
}
if(uploadFile != null){ //Does not occur here
...
}
If uploadFile object is itself null then it means you are calling isEmpty() on a null which throws the NPE
You can combine the condition like
uploadFile != null && !uploadFile.isEmpty()

Hibernate flush optimization using `hibernate.ejb.use_class_enhancer`

I am trying to use the hibernate feature that enhances the flush performance without making code changes. I came across the option hibernate.ejb.use_class_enhancer.
I made the following changes.
1) enabled the property hibernate.ejb.use_class_enhancer to true.
Build failed with error 'Cannot apply class transformer without LoadTimeWeaver specified'
2) I added
context:load-time-weaver to the context files.
Build failed with the following error :
Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring’s agent: -javaagent:spring-agent.jar
3) I added the following to the maven-surefire-plugin
javaagent:${settings.localRepository}/org/springframework/spring-
agent/2.5.6.SEC03/spring-agent-2.5.6.SEC03.jar
the build is successful now.
We have an interceptor that tracks the number of entities being flushed in a transaction.
After I did the above changes, I was expecting that number to come down significantly, but, they did not.
My question is:
Are the above changes correct/enough for getting the 'entity flush optimization'?
How to verify that the application is indeed using the optimization?
Edit:
After debugging, I found the following.
There is a time when our DO class is submitted for transformation, but, the logic that figures out whether a given class is supposed to be transformed is not handling the class names correctly (in my case), because of that, the DO class goes without being transformed.
Is there a way I can pass my logic instead ?
the relevant code is below.
The return copyEntities.contains( className ); is coming out false for the following inputs.
copyEntities contains list of strings "com.x.y.abcDO", "com.x.y.asxDO" where are the className is "com.x.y.abcDO_$$_jvsteb8_48"
public InterceptFieldClassFileTransformer(List<String> entities) {
final List<String> copyEntities = new ArrayList<String>( entities.size() );
copyEntities.addAll( entities );
classTransformer = Environment.getBytecodeProvider().getTransformer(
//TODO change it to a static class to make it faster?
new ClassFilter() {
public boolean shouldInstrumentClass(String clas sName) {
return copyEntities.contains( className );
}
},
//TODO change it to a static class to make it faster?
new FieldFilter() {
#Override
public boolean shouldInstrumentField(String clas sName, String fieldName) {
return true;
}
#Override
public boolean shouldTransformFieldAccess(
String transformingClassName, String fieldOwnerClassName, String fieldName
) {
return true;
}
}
);
}
edited on June 15th
I updated my project to use Spring 4.0.5.RELEASE and hibernate to 4.3.5.Final
I started using org.hibernate.jpa.HibernatePersistenceProvider
and
org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver
and
hibernate.ejb.use_class_enhancer=true
with these changes, I am debugging the flush behavior. I have a question in this code block .
private boolean isUnequivocallyNonDirty(Object entity) {
if(entity instanceof SelfDirtinessTracker)
return ((SelfDirtinessTracker) entity).$$_hibernate_hasDirtyAttributes();
final CustomEntityDirtinessStrategy customEntityDirtinessStrategy =
persistenceContext.getSession().getFactory().getCustomEntityDirtinessStrategy();
if ( customEntityDirtinessStrategy.canDirtyCheck( entity, getPersister(), (Session) persistenceContext.getSession() ) ) {
return ! customEntityDirtinessStrategy.isDirty( entity, getPersister(), (Session) persistenceContext.getSession() );
}
if ( getPersister().hasMutableProperties() ) {
return false;
}
if ( getPersister().getInstrumentationMetadata().isInstrumented() ) {
// the entity must be instrumented (otherwise we cant check dirty flag) and the dirty flag is false
return ! getPersister().getInstrumentationMetadata().extractInterceptor( entity ).isDirty();
}
return false;
}
In my case, the flow is returning false because of persister saying yes for hasMutableProperties. I think the interceptor did not have a chance to answer at all.
Is it not that the bytecode transformer cause an interceptor here? Or the bytecode transform should make the entity a SelfDirtinessTracker?
Can anyone explain, what is the behavior I should expect here from the bytecode transformation here.

Access Session In Global.asax Methods in MVC3 Environment [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why HttpContext.Current.Session is null in Global.asax?
I am developing a MVC3 project (Razor).
I added a variable to my session in some Controller/Action (different per user).
I want to access this variable in Application_AuthenticateRequest method (global.asax).
This exception happened:
Session state is not available in this context.
Sample Project
For startes, see https://stackoverflow.com/a/4185982/717732
The whole point is that Session is not available and simply will never be available at this point of time: and by 'time' I mean 'when this event is fired'.
Read the lifecycle for example at devproconnections.com/article/aspnet2/
The Session object is prepared much later: during the AcquireRequestState event. This is the first 'time' when you can access the Session statebag and investigate it.
Thanks quetzalcoatl,
This is true.
try
{
if (Session != null)
{
if (Session["mys"] != null)
{
//Error
string s = HttpContext.Current.Session["mys"].ToString();
}
else
{
Response.Redirect("~/Home/Index");
Response.End();
}
}
}
catch {
Response.Redirect("~/Home/Index");
Response.End();
}

AJAC MVC3 Request object and raw Ajax data, where the heck is it?

If this was a regular post of a form I could go to Request.Form['somevalue'] and get the value. If this was a get with a query string I could go to Request.QueryString["somevalue"] and get the value.
Where is the raw data when you post an ajax request. I need a value out of the raw data string in a filter method.
Any help will be appreciated!!
Edits below:
public class ValidateAntiForgeryId : FilterAttribute, IAuthorizationFilter {
public void OnAuthorization(AuthorizationContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
Guid filterGuid;
Guid.TryParse(filterContext.RequestContext.HttpContext.Request.Form["__sessionId"], out filterGuid);
if (filterGuid == Guid.Empty)
throw new AuthenticationException("Authentication failure");
try {
var cookieGuid = (Guid)filterContext.RequestContext.HttpContext.Items["SessionId"];
} catch {
throw new AuthenticationException("Authentication failure");
}
}
The posted data looks like this:
{"SsnLastFour":"2222","AccountNumber":"B112233","__sessionId":"dca0a504-3c40-4118-ae19-afefb9bfc8bd"}
I need access to the __sessionId chunk inside the filter.
There's nothing magic about AJAX posts. They're just plain old HTTP. That means you have plain old HTTP post values, and/or plainold HTTP Get values.
If you're not seeing them, it probably means you're not actually submitting them.
EDIT:
Two issues you did not include in your original question: 1) That this is JSON, and 2) That this is in an AuthorizationFilter (rather than an action method).
Both change the answers. Since ASP.NET does not natively understand JSON post values, you will have to parse them, via Request.InputStream. MVC3 by default has a JSON model binder, but AuthorizationFilters execute before model binders do, so you will be accessing things prior to the model binders being executed, and as such FormsCollection won't be populated (Request.Form[] won't work either, because as I said, asp.net doesn't natively understand JSON).
You may find that installing JSON.net via nuget may help with this task. Or you might just write a simple parse routine, since you know exactly what you're looking for.
You can accept the parameter values the same way you accept in normal form post.
Ex :
$.get("User/Get", { userId : "24"} ,function(data){
alert(data);
});
or
$("#yourDivId").load("User/Get?userId=23");
Your action method should look like
public ActionResult Get(int userId)
{
// you have value present in userId
if(Request.IsAjax())
{
return View("Partial/MyPartialView");
}
return View();
}
One thing you have to remember is, the parameter name of your action method should be same as of what your parameter/querystring name.
The fitlerContext has an ActionParameters collection which should have the parsed JSON properties (in case that helps). This may be easier than parsing the InputStream.
var sessionId = filterContext.ActionParameters["__sessionId"];

Resources