@DataJpaTest fail to update

I am using H2 as my testing database.  My testing code looks like as follows:
@Test
    public void shouldBeAbleToUpdateHrUserNameByUserId(){
        final User user = userRepository.findOne(“2”);
        final String originalHrUsername = user.getHrUserName();
        final String UPDATED_HR_USERNAME = “luketong”;
        assertThat(originalHrUsername, is(ORIGINAL_HR_USERNAME));
        userRepository.updateHrUsernameBy(“2”, UPDATED_HR_USERNAME);
        final User updatedUser = userRepository.findOne(“2”);
        assertNotNull(updatedUser);
        final String updateHrUsername = updatedUser.getHrUserName();
        assertThat(updateHrUsername, is(UPDATED_HR_USERNAME));
    }
The test case failed in the last assert. I tried to debug it and to my surprise I found both updatedUser  and user point to the same memory address. If this is the case of course I can’t get the assertion passed. But the question is why they point to the same memory address?
DataJpaTest not work1
A: According to https://stackoverflow.com/questions/45617040/datajpatest-fail-to-update-in-unit-test in order to clear the underlying persistence context after executing the modifying query, you need to add an extra attribute of the annotation @Modifying as @Modifying(clearAutomatically = true)
After the change, the two user instances no longer point to the same memory address as shown below, and my test case  passed.

DataJpaTest not work2

Please be noted in my original approach, the update SQL statement is displayed in console.
Advertisements

AngularJS post not work

Q: AngularJS script is made (as shown below) and it is supposed to make a REST POST call to SpringBoot embeded tomcat server and then display “I am happy” dialog.

app.factory(‘voiceRecorderStatus’, function ($http) {
var o = {};
o.config = {};
o.checks = {};
o.getVoiceRecorderConfig = function () {
var dataObj = {
name: ‘abcdef’,
macAddress: ‘5006AB812A25’,
location: ‘Sydney’
};
var config = {
headers: {
‘Content-Type’: ‘application/json’
}
};

$http.post(‘http://localhost:8080/api/healthcheck’, JSON.stringify(dataObj), config)
.success(function (data, status, headers, config) {
alert(“I am happy”+ JSON.stringify(data));
})
.error(function (data, status, header, config) {
alert(“I am not happy” + data);

});

};
return o;

});

However it displays a “I am not happy” box and even does not go to the breakpoint in IntelliJ(I run the service in IntelliJ IDE) The behavior of postman is it will go to the break point of my controller.
A: right click in your Chrome browser. Hit “Inspect” it will display
2
Hit the “Console” tab it will display as :
3.png
The root cause is the No ‘Access-Control-Allow-Origin’
We can add the @CrossOrigin annotation in front of the method as shown below to resolve this problem.
@CrossOrigin
@RequestMapping(value=”/api/ping”, method=”GET”)
public ResponseEntity<String> ping(){
……
//some biz logic
……
return ResponseEntity.ok(“Hello”);
}

How to convert JSON to different objects?

Q: How to convert JSON to a complicated object? for instance List<MyObject>?
ObjectMapper mapper = new ObjectMapper();
JavaType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, MyObject.class);
List<MyObject> readValue = mapper.readValue(jsonString, collectionType);

Q: How to convert JSON to a Java object?
ObjectMapper mapper = new ObjectMapper();
MyObject myObject  = mapper.readValue(new StringReader(jsonString), MyObject.class);

Q: How to marshal a Java object to JSON?
MyObject myObject = new MyObject();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(myObject));

Q: How to convert a JSON structured String/File to JsonNode
final String filePath = “testData/amqpRequestMessages/” + fileName + “.json”;
final String jsonString = Resources.toString(Resources.getResource(filePath), UTF_8);
final JsonNode internetDmRequest = objectMapper.readTree(jsonString);

Q: How to convert a JSON File to an Object
mapper = new ObjectMapper();
final InputStream inputStream = getClass().getResourceAsStream(“/configuration/createInternet.json”);
Configuration configuration = mapper.readValue(inputStream, Configuration.class);

Q: How to convert a JSON structured String to JsonNode

import com.fasterxml.jackson.databind.JsonNode;
final String payload = “{\”data\”: {\”subscriberId\” : \”test-subscriberId\”}}”;
JsonNode payloadParams = new ObjectMapper().readTree(payload);

Q: How to convert a JSON tree to a Java object
JsonNode dataNode = ……
AccessDMRequestData accessDMRequestData = objectMapper.treeToValue(dataNode.get(“data”), AccessDMRequestData.class);

Java8 lambda expression variable

public class TrickyLambdaExpressionDemo {
public static void main(String …args){
String name = “Hello World”;
Runnable r1 = ()-> System.out.println(name);

String name1 = “”;
name1 = name.toUpperCase();
Runnable r2 = ()-> System.out.println(name1);

r1.run();
}
}

What will be the result, if you run the above code?

The answer is “Compile Error”. The error is “Variable used in Lambda expression must be effectively final”.

If you change it to

String name1 = name.toUpperCase();

Then it will print out “Hello World”

Another point we should pay attention to is the word “effectively final” what is the difference between final and effectively final?

I always think lambda expression is a kind of anonymous class. In Java any local variable within an anonymous class should be final! Thus it is reasonable lambda expression requires variable to be final. But why effectively final? it means although the developer does not put the keyword final in front of the variable, in the above sample it is name1, if once it has been initialised,  the value never changed, the variable can be treated as final. This saves developer a lot of time to avoiding put the keyword final in front of any lambda variables.

Couchbase document can be found in console but cant be found in program

Q: Couchbase document can be found in console but can’t be found in program. In console if you run the following command it will find the required document. It is working totally in the sqi env.

curl http://:8093/query/service -d ‘statement=select * from `uat` where any myorder IN orders SATISFIES myorder.id=”12345678″ END &creds=[{“user”:,”pass”:””}]’

However in the application the same statement is executed, it returns 0 result. The code looks like this:

public ServiceInventory getServiceInventoryByOrderId(final String orderId) throws ServiceInventoryException {
final String PLACEHOLDER_STATEMENT =
“select * from `” + this.bucketName + “` USE INDEX(orderid_idx) where any myorder IN orders SATISFIES myorder.id = ‘” + orderId +”‘ END”;
log.debug(“The statement we are going to execute is {}”, PLACEHOLDER_STATEMENT);

final N1qlQueryResult result = this.executeN1qlQuery(N1qlQuery.simple(PLACEHOLDER_STATEMENT));
log.info(“The size of the query result is {}”, result.allRows().size());
final List serviceInventoryList = result.allRows().stream().map(n1qlQueryRow -> {
final JsonObject document = (JsonObject) n1qlQueryRow.value().get(this.bucketName);
if (document == null) {
log.info(“Can not find anything based on {}”, this.bucketName);
}
return gsonObj.fromJson(document.toString(), ServiceInventory.class);
}).collect(Collectors.toList());

if (CollectionUtils.isEmpty(serviceInventoryList)) {
throw new ServiceInventoryException(
“Can not find a matched Service Inventory Object by orderId = ” + orderId);
}

return serviceInventoryList.get(0);

}

A:Why it is so weird? Why it is working ONLY in console?

In the method executeN1qlQuery(…) log.debug(“bucket.query time = [{}] “, System.currentTimeMillis() – startTime); can be executed, it got stuck in bucket.query(query). So what is the connection string in the bucket?
There is an assumption here, the connection String in the code is the same as the command I ran in console. But is it really the same? No. If you replace stl-nbn-cb45e-uat-cl001.np.stl.np.top.corp.telstra.com with the connection string I use in code, the execution of the command will be failed.

Postman call is successful but in code the same URL, the REST call is failed

Q: I was asked to write a REST call to a third party address service. Everything is fine but when we are trying to test it on code base level, it failed! The call to https:///v1/ failed. But it is successful in postman, how come? It is weird.

A: The service address call is a two-steps call, one is to get the token the second step is insert this token into headers and do a REST call. After investigating, I found the problem is in the headers. Below is the code:
private HttpHeaders getHttpHeaders(final String token, final String correlationId) {
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
It seems like the downstream system does not like UTF8. So if you change it to:
private HttpHeaders getHttpHeaders(final String token, final String correlationId) {
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return headers;
}
The problem is resolved.

My experience in pair programming

My previous company is very famous for its pair programming, below are my thoughts

pros:
  • more efficient;
  • in conjunction with TDD, less bug;
  • easier to setup (when you are new);
  • know the whole project;
  • easy to transfer knowledge from senior to new comer;
  • as a single developer it is very easy to miss some possibility/risk for a solution, but for pair programming your pair may help you.
cons:
  • if your pair is sick (or in absence), then you can’t do anything, especially when you are new.
  • less private. I do think, especially in programming, sometimes you need to concentrate, you need to work alone; Working alone sometimes can reach higher quality;
  • Feel pressure when sb is “monitoring” you. I am not lazy just feel uncomfortable or if you can’t fix a problem you will feel pressure
  • ow to do it when we outsource a lot to India?

Why always override hashcode() if overriding equals()?

This is one the most frequent questions I was asked in interview.

You can override the default implementation of the equals() method defined in java.lang.Object. If you override the equals(), you MUST also override hashCode(). Otherwise a violation of the general contract for Object.hashCode will occur, which can have unexpected repercussions when your class is in conjunction with all hash-based collections.

The default implementation of equals() method checks to see if the two objects have the same identity. Similarly, the default implementation of the hashCode() method returns an integer based on the object’s identity and is not based on the values of instance (and class) variables of the object. No matter how many times the values of its instance variables (data fields) change, the hash code calculated by the default hashCode implementation does not change during the life of the object.

Consider the following code, we have overridden equals() method to check if two objects are equal based on the values of their instance variables. Two objects may be stored at different memory addresses but may still be equal base on their instance variable.

public class CustomerID {
private long crmID;
private int nameSpace;

public CustomerID(long crmID, int nameSpace) {
super();
this.crmID = crmID;
this.nameSpace = nameSpace;
}

public boolean equals(Object obj) {
//null instanceof Object will always return false
if (!(obj instanceof CustomerID))
return false;
if (obj == this)
return true;
return this.crmID == ((CustomerID) obj).crmID &&
this.nameSpace == ((CustomerID) obj).nameSpace;
}

public static void main(String[] args) {
Map m = new HashMap();
m.put(new CustomerID(2345891234L,0),”Jeff Smith”);
System.out.println(m.get(new CustomerID(2345891234L,0)));
}

}

Compile and run the above code, the output result is

null
What is wrong? The two instances of CustomerID are logically equal according to the class’s equals method. Because the hashCode() method is not overridden, these two instances’ identities are not in common to the default hashCode implementation. Therefore, the Object.hashCode returns two seemingly random numbers instead of two equal numbers. Such behavior violates “Equal objects must have equal hash codes” rule defined in the hashCode contract.

Let’s provide a simple hashCode() method to fix this problem:

public class CustomerID {
private long crmID;
private int nameSpace;

public CustomerID(long crmID, int nameSpace) {
super();
this.crmID = crmID;
this.nameSpace = nameSpace;
}

public boolean equals(Object obj) {
//null instanceof Object will always return false
if (!(obj instanceof CustomerID))
return false;
if (obj == this)
return true;
return this.crmID == ((CustomerID) obj).crmID &&
this.nameSpace == ((CustomerID) obj).nameSpace;
}

public int hashCode() {
int result = 0;
result = (int)(crmID/12) + nameSpace;
return result;
}

public static void main(String[] args) {
Map m = new HashMap();
m.put(new CustomerID(2345891234L,0),”Jeff Smith”);
System.out.println(m.get(new CustomerID(2345891234L,0)));
}

}
Compile and run the above code, the output result is

Jeff Smith

Code Coverage Result is defferent when use Jacoco

Q: The code coverage for my microservice is always low, even for some classes the code coverage is 0%, how come? since when I run it locally it is 100% code coverage, it should not have such a big gap.
A: According to https://github.com/powermock/powermock/issues/422 it seems like Jacoco is not very friend with PowerMock. Unfortunately my test cases are using PowerMock (since I can test private method through Powermock)
After switch from Powermock to Mockito, my problem fixed.