Is there a Hamcrest macher that matches public fields? - unit-testing

I have different value objects, each with a different set of fields. How can I check against these with a Hamcrest matcher?
public class ValueObjectA {
public Integer field1;
public String field2;
public long filed3;
public Object filed4;
}
public class ValueObjectB {
public String field1;
public int field2;
}
This is, what I want to do:
resultA = getResultA();
ValueObjectA expectedA = new ValueObjectA();
expectedA.field1 = 4;
resultB = getResultB();
ValueObjectB expectedB = new ValueObjectB();
expectedB.field1 = "foo";
assertThat(resultA, new ValueObjectMatcher(expectedA));
assertThat(resultB, new ValueObjectMatcher(expectedB));
I found a PropertyMatcher but that only uses public getters. I can write something similar, that uses reflection to get the public fields. But is there a readymade one?

You can use a library we recent open sourced for doing this. It works similar to the PropertyMatcher but was designed to do deep object graphs. An upshot is that it "just works" on public fields.
shazamcrest on github

Anyway, I wrote something based on the PropertyMatcher, in case someone wants to write unit tests for eg. com.j256.ormlite :
public class ValueObjectMatcher extends TypeSafeDiagnosingMatcher {
private final Object expectedVo;
private final Set<String> fieldNames;
private final List<FieldMatcher> fieldMatchers;
public ValueObjectMatcher(final Object expectedVo) {
Field[] fieldsToMatch = expectedVo.getClass().getFields();
this.expectedVo = expectedVo;
this.fieldNames = fieldNamesFrom(fieldsToMatch);
this.fieldMatchers = fieldMatchersFor(expectedVo, fieldsToMatch);
}
#Override
protected boolean matchesSafely(final Object item, final Description mismatchDescription) {
return hasAllFields(item, mismatchDescription) && hasMatchingValues(item, mismatchDescription);
}
#Override
public void describeTo(final Description description) {
description.appendText("same field values as " + expectedVo.getClass().getSimpleName())
.appendList(" <", ", ", ">", fieldMatchers);
}
private boolean hasMatchingValues(final Object item, final Description mismatchDescription) {
mismatchDescription.appendText(item + " has <");
int mismatchCount = 0;
for (FieldMatcher fieldMatcher : fieldMatchers) {
if (!fieldMatcher.matches(item)) {
if (mismatchCount != 0) {
mismatchDescription.appendText(", ");
}
fieldMatcher.describeMismatch(item, mismatchDescription);
mismatchCount++;
}
}
mismatchDescription.appendText(">");
return mismatchCount == 0;
}
private boolean hasAllFields(final Object item, final Description mismatchDescription) {
final Field[] fields = item.getClass().getFields();
final Set<String> itemsFieldNames = fieldNamesFrom(fields);
boolean result = true;
for (String fieldName : fieldNames) {
if (!itemsFieldNames.contains(fieldName)) {
result = false;
mismatchDescription.appendText("missing field: " + fieldName);
}
}
return result;
}
private List<FieldMatcher> fieldMatchersFor(final Object expectedVo, final Field[] fields) {
List<FieldMatcher> result = new ArrayList<FieldMatcher>(fields.length);
try {
for (Field field : fields) {
result.add(new FieldMatcher(field, expectedVo));
}
}
catch (NoSuchFieldException e) {
throw new IllegalStateException("Programmer exception, pls replace programmer: " +
"field list doesn't match with the fields of the provided expectedVo", e);
}
catch (IllegalAccessException e) {
throw new IllegalStateException("Programmer exception, pls replace programmer: " +
"field list doesn't match with the fields of the provided expectedVo", e);
}
return result;
}
private Set<String> fieldNamesFrom(final Field[] fieldsToMatch) {
HashSet<String> result = new HashSet<String>();
for (Field field : fieldsToMatch) {
result.add(field.getName());
}
return result;
}
public class FieldMatcher extends DiagnosingMatcher<Object> {
private final Object expectedFieldValue;
private final String fieldName;
private FieldMatcher(Field field, Object expectedVo) throws NoSuchFieldException, IllegalAccessException {
this.fieldName = field.getName();
this.expectedFieldValue = expectedVo.getClass().getField(fieldName).get(expectedVo);
}
#Override
protected boolean matches(final Object item, final Description mismatchDescription) {
try {
final Field fieldItem = item.getClass().getField(fieldName);
final Object fieldObjectItem = fieldItem.get(item);
if (fieldObjectItem == null) {
if (expectedFieldValue != null) {
mismatchDescription.appendText(fieldName + ": " + fieldObjectItem);
}
} else if (!fieldObjectItem.equals(expectedFieldValue)) {
mismatchDescription.appendText(fieldName + ": " + fieldObjectItem);
}
}
catch (IllegalAccessException e) {
mismatchDescription.appendText(fieldName + " is inaccessible");
e.printStackTrace();
}
catch (NoSuchFieldException e) {
mismatchDescription.appendText(fieldName + " doesn't exist");
e.printStackTrace();
}
return false;
}
#Override
public void describeTo(final Description description) {
description.appendText(fieldName + ": " + expectedFieldValue);
}
}
}

Related

How to process "data" part of GCP PubSub message into a HashMap?

I'm getting pubsub message as below :
{
"data": {
"systemId": "system-1",
"userId": "userId-1",
"departmentId": "090",
"enrolmentDateTime": "2022-08-19T15:44:29.080Z",
"event_type": "REGISTRATION"
}
}
I want to further process this message in my springboot application based on the "event_type".
How can I just fetch "event_type" from this message and use it for comparison?
Any suggestions?
For eg I want to have processing like this :
if(event_type.equals("REGISTRATION")) { registrationHandler.handle(message); else { }
I have tried converting a PubSubMessage into string and then further map it to HashMap using ObjectMapper, but that gives me "data" as key and rest of the json part as a value.
public void process(final PubsubMessage message) throws ConsumerException {
String data = message.getData().toStringUtf8();
try {
ObjectMapper mapper = new ObjectMapper();
HashMap<String, String> dataMap = mapper.readValue(data, HashMap.class);
} ....
Instead of using a Map, you can use a typed object, example :
PubSubData.java file :
public class PubSubData {
private String systemId;
private String userId;
private String departmentId;
private String enrolmentDateTime;
private String event_type;
public PubSubData() {
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getDepartmentId() {
return departmentId;
}
public void setDepartmentId(String departmentId) {
this.departmentId = departmentId;
}
public String getEnrolmentDateTime() {
return enrolmentDateTime;
}
public void setEnrolmentDateTime(String enrolmentDateTime) {
this.enrolmentDateTime = enrolmentDateTime;
}
public String getEvent_type() {
return event_type;
}
public void setEvent_type(String event_type) {
this.event_type = event_type;
}
}
PubSubResult.java file :
public class PubSubResult {
private PubSubData data;
public PubSubResult() {
}
public PubSubData getData() {
return data;
}
public void setData(PubSubData data) {
this.data = data;
}
}
Example of an unit test that deserializes data from PubsubMessage to the PubSubResult object :
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.PubsubMessage;
import org.junit.Test;
public class MyTest {
private static final ObjectMapper OBJECT_MAPPER;
static {
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
OBJECT_MAPPER = mapper;
}
#Test
public void testDeserializePubSubData() {
final String data = "{\n" +
" \"data\": {\n" +
" \"systemId\": \"system-1\",\n" +
" \"userId\": \"userId-1\",\n" +
" \"departmentId\": \"090\",\n" +
" \"enrolmentDateTime\": \"2022-08-19T15:44:29.080Z\",\n" +
" \"event_type\": \"REGISTRATION\"\n" +
" }\n" +
"}";
final PubsubMessage message = PubsubMessage.newBuilder()
.setData(ByteString.copyFrom(data.getBytes()))
.build();
final String dataResult = message.getData().toStringUtf8();
final PubSubResult resultData = deserialize(dataResult);
// Access to the event type.
final String eventType = resultData.getData().getEvent_type();
}
private PubSubResult deserialize(final String value) {
try {
return OBJECT_MAPPER.readValue(value, PubSubResult.class);
} catch (JsonProcessingException e) {
throw new IllegalStateException("Error !!", e);
}
}
}

DynamoDB: Enum as partition key giving error "Missing the key id in the item" when putItem

I am using the enum as the partition key and my model looks like below
#DynamoDbBean
public class Item {
public enum Key {
KEY_A(false),
KEY_B(2),
private final Object defaultValue;
private Key(Object defaultValue) {
this.defaultValue = defaultValue;
}
public Object getDefaultValue() {
return this.defaultValue;
}
}
private Key key;
private Object value;
public Item() {
}
public Item(Key key) {
this.key = key;
this.value = key.getDefaultValue();
}
#DynamoDbConvertedBy(KeyEnumConverter.class)
#DynamoDbPartitionKey
public Key getKey() {
return key;
}
public void setKey(Key key) {
this.key = key;
}
#DynamoDbConvertedBy(ValueConverter.class)
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
My Converter classes to convert between java object and DDB data type is as below:
public class KeyEnumConverter implements AttributeConverter<Item.Key> {
#Override
public AttributeValue transformFrom(Item.Key key) {
return EnhancedAttributeValue.fromString(key.toString()).toAttributeValue();
}
#Override
public Item.Key transformTo(AttributeValue attributeValue) {
return Item.Key.valueOf(attributeValue.s());
}
#Override
public EnhancedType<Item.Key> type() {
return EnhancedType.of(Item.Key.class);
}
#Override
public AttributeValueType attributeValueType() {
return AttributeValueType.S;
}
public class ValueConverter implements AttributeConverter<Object> {
#Override
public AttributeValue transformFrom(Object Value) {
return getEnhancedAttributeValue(Value).toAttributeValue();
}
#Override
public Object transformTo(AttributeValue attributeValue) {
return JsonConvertor.getObjectFromJsonString(attributeValue.s(), Object.class);
}
#Override
public EnhancedType<Object> type() {
return EnhancedType.of(Object.class);
}
#Override
public AttributeValueType attributeValueType() {
return AttributeValueType.S;
}
private EnhancedAttributeValue getEnhancedAttributeValue (Object value) {
if (Value instanceof Boolean) {
return EnhancedAttributeValue.fromBoolean((Boolean)Value);
} else if(value instanceof Number) {
return EnhancedAttributeValue.fromNumber(String.valueOf(value));
} else {
throw new IllegalArgumentException("Please add support for type " + value.getClass().getSimpleName());
}
}
}
When I am putting an item into the table:
public void saveItem (String itemKey) {
Table.putItem(new Item(Item.Key.valueOf(itemKey)));
}
I got the error:
One or more parameter values were invalid: Missing the key id in the item
The partitionKey is defined in the model, why the key id still missing

how to prevent to creating the duplicate item while scrolling my recyclerview

Here is My AdapterClass AvailablePateientAdapter.java
plaese let me know the how to resolve this issue while scrolling my recyclerview each time increasing the duplicate items
Thanks in advance.
public class AvailablePatientsAdapter extends RecyclerView.Adapter<AvailablePatientsAdapter.AvailablePatientListViewHolder> {
static ReportData patData = null;
private static String niramaiID= null;
static ProgressBar progBar ;
private static ProgressDialog progressDialog;
private static LayoutInflater mInflater = null;
private static ViewPendingList viewPendingList;
private static List<PatientData> patients;
private static Context mContext;
static boolean isPending = false;
int postion;
private static boolean clicked = true;
static String repStatus ;
static Handler viewPatHandler= new Handler(){
#Override
public void handleMessage(Message msg){
patData.setStatusReport(repStatus);
// progressDialog.show();
if(niramaiID != null) {
if (msg.what == 1) {
getexaminationtable(niramaiID);
} else if (msg.what == 2) {
getsegmentationtable(niramaiID);
} else if (msg.what == 3) {
getthanalysistable(niramaiID);
} else if (msg.what == 4) {
Log.d(Config.LOG_TAG, "Response:1 status report " + patData.getStatusReport());
String viewPat = patData.toJson();
Intent addPatFromEdit = new Intent();
addPatFromEdit.setClass(mContext, DisplayReport.class);
addPatFromEdit.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
addPatFromEdit.putExtra("display_report", viewPat);
// addPatFromEdit.putExtra("is_pending",isPending);
if(progressDialog.isShowing()) {
progressDialog.hide();
}
mContext.startActivity(addPatFromEdit);
progBar.setVisibility(View.GONE);
}
}else
{
if(progressDialog.isShowing()) {
progressDialog.hide();
}
Toast.makeText(mContext,"Niramai id is null ",Toast.LENGTH_SHORT).show();
}
}
};
static class AvailablePatientListViewHolder extends RecyclerView.ViewHolder{
private static SimpleDateFormat oudSdf = new SimpleDateFormat("dd-MMM-yyyy");
private static SimpleDateFormat inSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
AvailablePatientsAdapter mPatientBinding;
ViewPendingList viewPendingList;
AvailablePatientListViewHolder(View itemView) {
super(itemView);
}
// public AvailablePatientListViewHolder(ViewPendingList viewPendingList,View item){
// super(item);
// this.viewPendingList = viewPendingList;
// }
void bind(final PatientData data) {
RelativeLayout b = itemView.findViewById(R.id.rel_available);
niramaiID = data.getNiramaiId();
// progBar.setVisibility(View.VISIBLE);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.postDelayed(new Runnable(){
#Override
public void run() {
Log.d(Config.LOG_TAG," data.getStatus() :: "+data.getStatus());
int muID;
if(NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,mContext) != 0)
{
muID = NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,mContext);
}else
{
muID = LoggedInUser.Users.getDetails().getMu().get(0).getId();
}
getPatientDetails(itemView.getContext(), data.getStatus(),muID ,data.getNiramaiId(),data.getPatientId(), itemView);
progBar.setVisibility(View.GONE);
}
},500);
}
});
TextView patientID = (TextView) itemView.findViewById(R.id.patientID);
TextView scandate = (TextView) itemView.findViewById(R.id.scanDate);
try {
scandate.setText(oudSdf.format(inSdf.parse(data.getScanDate())));
} catch (ParseException e) {
e.printStackTrace();
}
patientID.setText(data.getPatientId());
}
AvailablePatientsAdapter getPatientBinding(){
return this.mPatientBinding;
}
}
public AvailablePatientsAdapter(Context c, #Nullable List<PatientData> p){
mContext=c;
patients = p;
setHasStableIds(true);
progressDialog = new ProgressDialog(mContext);
progressDialog.setTitle("Please wait");
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
}
#Override
public AvailablePatientListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.available_patient_list, parent, false);
mContext = parent.getContext();
progBar = new ProgressBar(parent.getContext());
return new AvailablePatientListViewHolder(itemView);
}
#Override
public void onBindViewHolder(AvailablePatientListViewHolder holder, int position) {
// Log.e("ADAPTER","pos:"+position );
final PatientData p = patients.get(position);
holder.bind(p);
holder.setIsRecyclable(false);
}
#Override
public int getItemCount() {
return patients.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
public void setPatientList(List<PatientData> p, Boolean isPendingActivity){
isPending = isPendingActivity;
patients = p;
notifyDataSetChanged();
}
// Dharam
public void clickOnRecyclerViewItem(boolean click){
clicked = click;
}
private static void getPatientDetails(final Context context, final String status, int muID, String niramaiID, String pID, final View itemView){
if(!progressDialog.isShowing()) {
progressDialog.show();
}
ApiInterface mApiService = RetrofitFactory.getInterfaceService();
Log.d(Config.LOG_TAG,"Call Start muID in Av Report :: "+muID+" niramaiID :: "+niramaiID+" pID :: "+pID);
repStatus = status;
mApiService.getPatientReportData(muID,niramaiID,pID).enqueue(new Callback<ReportData>() {
#Override
public void onResponse(Call<ReportData> call, Response<ReportData> response) {
patData = response.body();
Log.d(Config.LOG_TAG,"patData status color "+ patData);
// progBar.setVisibility(View.VISIBLE);
viewPatHandler.sendEmptyMessage(1);
}
#Override
public void onFailure(Call<ReportData> call, Throwable t) {
// itemView.setClickable(true);
Log.e(Config.LOG_TAG,"An getPatientDetails Error Occured: "+t.getMessage());
}
});
}
private static void getexaminationtable(String niramaiId) {
ApiInterface mApiService = RetrofitFactory.getInterfaceService();
Log.d(Config.LOG_TAG,"getexaminationtable Start");
if(!progressDialog.isShowing()) {
progressDialog.show();
}
mApiService.getExaminationTable(niramaiId).enqueue(new Callback<List<CBEData>>() {
#Override
public void onResponse(Call<List<CBEData>> call, Response<List<CBEData>> response) {
Log.d(Config.LOG_TAG, "Response Body :: "+response.body());
if(response.body() != null && response.body().size()>=1) {
viewPatHandler.sendEmptyMessage(2);
}
}
#Override
public void onFailure(Call<List<CBEData>> call, Throwable t) {
Log.e(Config.LOG_TAG,"An getexaminationtable Error Occured: "+t.getMessage());
}
});
}
private static void getsegmentationtable(String niramaiId) {
ApiInterface mApiService = RetrofitFactory.getInterfaceService();
Log.d(Config.LOG_TAG,"getsegmentationtable Start");
if(!progressDialog.isShowing()) {
progressDialog.show();
}
mApiService.getSegmentationTable(niramaiId).enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
response.body();
viewPatHandler.sendEmptyMessage(3);
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e(Config.LOG_TAG,"An getsegmentationtable Error Occured: "+t.getMessage());
}
});
}
private static void getthanalysistable(String niramaiId) {
ApiInterface mApiService = RetrofitFactory.getInterfaceService();
Log.d(Config.LOG_TAG,"getthanalysistable Start");
if(!progressDialog.isShowing()) {
progressDialog.show();
}
mApiService.getthanAlysisTable(niramaiId).enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
response.body();
viewPatHandler.sendEmptyMessage(4);
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
Log.e(Config.LOG_TAG,"An getthanalysistable Error Occured: "+t.getMessage());
}
});
}
}
Here is my Activity AvailablePateint.class
can you please let me know also why is it occurring each time while scrolling each time.
public class AvailablePatients extends Activity {
#BindView(R.id.patientsSwipeView) SwipeRefreshLayout swipeContainer;
#BindView(R.id.patientList) RecyclerView patientListView;
#BindView(R.id.searchBox) EditText searchBox;
private Context context;
private boolean clicked;
static String MY_PREFS_NAME = "NIRAMAI_PREFERENCE";
String LOG_TAG = "Niramai";
ApiInterface mApiService;
List<PatientData> allPatientData;
List<PatientData> displayPatientData;
List<PatientData> filteredPatientData;
List<PatientData> availablePatData;
Patients patient;
// List<patient_> patient_ = null;
private AvailablePatientsAdapter mPA;
private user mLoginObject;
// List<IndividualPatient> eachpatient = null;
#BindView(R.id.drawerView) PlaceHolderView mDrawerView;
#BindView(R.id.drawerLayout) DrawerLayout mDrawer;
#BindView(R.id.toolbar_all) Toolbar mToolbar;
int muid = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final_report);
availablePatData = new ArrayList<>();
context = this;
ButterKnife.bind(this);
mLoginObject = LoggedInUser.Users.getDetails();
if(mLoginObject == null)
{
Toast.makeText(this,"Please Login Again !!",Toast.LENGTH_LONG).show();
Intent myIntent = new Intent(this, LoginActivity.class);
//dharam
myIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY|Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK );
ComponentName cn = myIntent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
finish();
}
SharedPreferences pref = getSharedPreferences("NiramaiPrefrence", Context.MODE_PRIVATE);
if(mLoginObject != null) {
muid = mLoginObject.getMu().get(0).getId();
}
mPA = new AvailablePatientsAdapter(this,new ArrayList<PatientData>());
patientListView.setLayoutManager(new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL,
false));
RecyclerSectionItemDecoration sectionItemDecoration =
new RecyclerSectionItemDecoration(false,getResources().getDimensionPixelSize(R.dimen.recycler_section_header_height),
true,
getSectionCallback());
patientListView.addItemDecoration(sectionItemDecoration);
patientListView.setAdapter(mPA);
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
displayPatientData = new ArrayList<>();
if(availablePatData==null) return;
for(PatientData pd : availablePatData){
if (pd.getPatientId().contains(charSequence)){
displayPatientData.add(pd);
}
}
Collections.sort(displayPatientData, new Comparator<PatientData>() {
#Override
public int compare(PatientData p1, PatientData p2) {
return p1.getPatientId().compareTo(p2.getPatientId());
}
});
mPA.setPatientList(displayPatientData,false);
}
#Override
public void afterTextChanged(Editable editable) {
}
});
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeContainer.setRefreshing(true);
if(NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,AvailablePatients.this) != 0) {
getAllPatientDataWithRetrofit((NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,AvailablePatients.this)));
}else
{
getAllPatientDataWithRetrofit(muid);
}
}
});
swipeContainer.setRefreshing(true);
if(NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,AvailablePatients.this) != 0) {
getAllPatientDataWithRetrofit((NiramaiMythriApplication.getDefaultInt(UNINVERSAL_MUID,AvailablePatients.this)));
}else
{
getAllPatientDataWithRetrofit(muid);
}
setupDrawer();
}
private RecyclerSectionItemDecoration.SectionCallback getSectionCallback() {
return new RecyclerSectionItemDecoration.SectionCallback() {
#Override
public boolean isSection(int position) {
return false;
}
#Override
public CharSequence getSectionHeader(int position) {
return "Patient ";
}
};
}
private void availablePatData(List<PatientData> patData) {
int j = 0;
Log.d(Config.LOG_TAG, "size" + patData.size());
for (int i = 0; i < patData.size(); i++) {
// Log.d(Config.LOG_TAG, "Patient id" + patData.get(i).getPatientId());
if (patData.get(i).getStatus().equalsIgnoreCase(getResources().getString(R.string.report_status_available)) ||
patData.get(i).getStatus().equalsIgnoreCase(getResources().getString(R.string.report_status_screening_done))) {
availablePatData.add(j,patData.get(i));
j++;
}
}
}
private void getAllPatientDataWithRetrofit(int muID) {
mApiService = RetrofitFactory.getInterfaceService();
Call mService = mApiService.getAllPatients(muID);
mService.enqueue(new Callback<List<Patients>>() {
#Override
public void onResponse(Call<List<Patients>> call, Response<List<Patients>> response) {
if(response.isSuccessful()) {
patient= response.body().get(0);
allPatientData = patient.getPatientData();
try {
filteredPatientData = filterPatients(allPatientData);
} catch (ParseException e) {
e.printStackTrace();
}
availablePatData(filteredPatientData);
displayPatientData = availablePatData;
mPA.setPatientList(displayPatientData,false);
mPA.notifyDataSetChanged();
swipeContainer.setRefreshing(false);
Log.d(LOG_TAG,"Response string is ::: "+ patient.toString());
}
}
#Override
public void onFailure(Call<List<Patients>> call, Throwable t) {
call.cancel();
swipeContainer.setRefreshing(false);
Log.e(LOG_TAG,"getAllPatientDataWithRetrofit process failed in response: "+t.getMessage());
}
});
if(mService.isExecuted())
{
}
}
// Filters All patient to keep only single latest record of each patient id
private List<PatientData> filterPatients(List<PatientData> allPatientData) throws ParseException {
HashMap<String ,Pair<PatientData,Date>> filtered = new HashMap<>();
SimpleDateFormat inSdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
for(PatientData p : allPatientData){
if(filtered.containsKey(p.getPatientId())){
Pair<PatientData,Date> _p = filtered.get(p.getPatientId());
Date d1 = _p.second;
Date d2 = inSdf.parse(p.getScanDate());
if(d2.after(d1)){
filtered.put(p.getPatientId(), new Pair<>(p, d2));
}
}else{
if(p.getScanDate() != null)
filtered.put(p.getPatientId(), new Pair<>(p, inSdf.parse(p.getScanDate())));
}
}
List<Pair<PatientData,Date>> filteredPairs = new ArrayList<>(filtered.values());
Collections.sort(filteredPairs,new Comparator<Pair<PatientData, Date>>() {
#Override
public int compare(Pair<PatientData, Date> t1, Pair<PatientData, Date> t2) {
if(t1.second.after(t2.second)){
return -1;
}else if (t1.second.before(t2.second)){
return 1;
}
else
return t1.first.getPatientId().compareTo(t2.first.getPatientId());
}
});
List<PatientData> filteredList = new ArrayList<>(filteredPairs.size());
for(Pair<PatientData,Date> p : filteredPairs){
filteredList.add(p.first);
}
return filteredList;
}
#Override
protected void onResume() {
super.onResume();
mPA.clickOnRecyclerViewItem(true);
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
private void setupDrawer(){
mDrawerView
.addView(new DrawerHeader())
.addView(new DrawerMenuItem(this.getApplicationContext(),1))
.addView(new DrawerMenuItem(this.getApplicationContext(),2))
.addView(new DrawerMenuItem(this.getApplicationContext(),3))
.addView(new DrawerMenuItem(this.getApplicationContext(),4));
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawer.addDrawerListener(drawerToggle);
drawerToggle.syncState();
}
}
Basically when we are adding new item in the list it needs refresh it but while refreshing it you will see the duplicates of the existing items because of previous list was not empty the list had some items. So clear the list first before adding the items in the list.
add the following changes in ActivityPatient.java
private void availablePatData(List<PatientData> patData) {
int j = 0;
if(availablePatData.size()>=0){
availablePatData.clear();
}
Log.d(Config.LOG_TAG, "size" + patData.size());
for (int i = 0; i < patData.size(); i++) {
// Log.d(Config.LOG_TAG, "Patient id" + patData.get(i).getPatientId());
if (patData.get(i).getStatus().equalsIgnoreCase(getResources().getString(R.string.report_status_available)) ||
patData.get(i).getStatus().equalsIgnoreCase(getResources().getString(R.string.report_status_screening_done))) {
availablePatData.add(j,patData.get(i));
j++;
}
}
}

EclipseLink JPA #OneToMany List is not same in differernt request of same session in Jesery REST

I have two entities as People and Story. Now I post my story and check my stories, but returns different Story List occasionally. I mean, usr.stories.hashCode() is not same in differernt request from the exactly same user. The database table is always correct, so I am very confused. I checked out Hibernate reference for better details, but it didn't help at all.
Model class:
#MappedSuperclass
public class People{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer id;
#OrderBy(value = "id DESC")
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "people")
public List<Story> stories = new LinkedList<Story>();
public People(){
}
}
#MappedSuperclass
public class Story{
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "people_id")
public People people;
#Column(name = "story", nullable = false)
public String story;
public Story(String story){
this.story = story;
}
}
REST class:
#Path("/story")
public class StoryRS {
#POST
public StreamingOutput create(final #Context HttpServletRequest req, final String story) throws IOException{
return new StreamingOutput() {
#Override
public void write(OutputStream os) {
HttpSession hs = req.getSession(false);
if (hs != null && story != null && story.trim().length() > 0) {
Integer uid = (Integer) hs.getAttribute("uid");
People usr = uid != null ? PeopleDAO.findById(uid) : null;
if (usr != null) {
Story obj = new Story(story);
EntityManagerHelper.beginTransaction();
StoryDAO.save(obj);
EntityManagerHelper.commit();
os.write(obj.id);
}
}
os.close();
}
};
}
#GET
public StreamingOutput create(final #Context HttpServletRequest req) throws IOException{
return new StreamingOutput() {
#Override
public void write(OutputStream os) {
HttpSession hs = req.getSession(false);
if (hs != null && story != null && story.trim().length() > 0) {
Integer uid = (Integer) hs.getAttribute("uid");
People usr = uid != null ? PeopleDAO.findById(uid) : null;
if (usr != null && usr.stories != null && usr.stories.size()>0) {
os.write(usr.stories...);
}
}
os.close();
}
};
}
}
PeopleDAO:
public class PeopleDAO{
#Override
public void save(People entity) {
try {
getEntityManager().persist(entity);
} catch (RuntimeException re) {
EntityManagerHelper.log("save failed", Level.SEVERE, re);
throw re;
}
}
#Override
public void delete(People entity) {
try {
entity = getEntityManager().getReference(People.class, entity.getId());
getEntityManager().remove(entity);
} catch (RuntimeException re) {
EntityManagerHelper.log("delete failed", Level.SEVERE, re);
throw re;
}
}
#Override
public People update(People entity) {
try {
People result = getEntityManager().merge(entity);
return result;
} catch (RuntimeException re) {
EntityManagerHelper.log("update failed", Level.SEVERE, re);
throw re;
}
}
#Override
public People findById(Integer id) {
try {
People instance = getEntityManager().find(People.class, id);
return instance;
} catch (RuntimeException re) {
EntityManagerHelper.log("find failed", Level.SEVERE, re);
throw re;
}
}
StoryDAO:
public class StoryDAO{
#Override
public void save(Story entity) {
try {
getEntityManager().persist(entity);
} catch (RuntimeException re) {
EntityManagerHelper.log("save failed", Level.SEVERE, re);
throw re;
}
entity.People.stories.add(0, entity);
}
#Override
public void delete(Story entity) {
try {
entity = getEntityManager().getReference(Story.class, entity.getId());
getEntityManager().remove(entity);
} catch (RuntimeException re) {
EntityManagerHelper.log("delete failed", Level.SEVERE, re);
throw re;
}
entity.People.stories.remove(entity);
}
#Override
public Story update(Story entity) {
try {
Story result = getEntityManager().merge(entity);
return result;
} catch (RuntimeException re) {
EntityManagerHelper.log("update failed", Level.SEVERE, re);
throw re;
}
}
#Override
public Story findById(Integer id) {
try {
Story instance = getEntityManager().find(Story.class, id);
return instance;
} catch (RuntimeException re) {
EntityManagerHelper.log("find failed", Level.SEVERE, re);
throw re;
}
}
EntityManagerHelper:
public class EntityManagerHelper {
private static final EntityManagerFactory emf;
private static final ThreadLocal<EntityManager> threadLocal;
private static final Logger logger;
static {
emf = Persistence.createEntityManagerFactory("db");
threadLocal = new ThreadLocal<EntityManager>();
logger = Logger.getLogger("db");
logger.setLevel(Level.ALL);
}
public static EntityManager getEntityManager() {
EntityManager manager = threadLocal.get();
if (manager == null || !manager.isOpen()) {
manager = emf.createEntityManager();
threadLocal.set(manager);
}
return manager;
}
public static void closeEntityManager() {
EntityManager em = threadLocal.get();
threadLocal.set(null);
if (em != null)
em.close();
}
public static void beginTransaction() {
getEntityManager().getTransaction().begin();
}
public static void commit() {
getEntityManager().getTransaction().commit();
}
public static void rollback() {
getEntityManager().getTransaction().rollback();
}
public static Query createQuery(String query) {
return getEntityManager().createQuery(query);
}
Thanks a lot for any response
Here's your problem
public static EntityManager getEntityManager() {
EntityManager manager = threadLocal.get();
if (manager == null || !manager.isOpen()) {
manager = emf.createEntityManager();
threadLocal.set(manager);
}
return manager;
}
EntityManager's are supposed to be short-lived objects. They're cheap to make and cheap to destroy. It also explains why you are getting inconsistent results. EntityManagers have an internal cache which is surprisingly aggressive.
The rule for working with EM's is "One EntityManager per transaction."
Change your code to get a new EM every time and your problems will go away.

IList List is null in my Composition Class .. WHY?

I am usling IList List property to get a list of students class in University class .. as i try to access this list in department Class which is a part of university class .. the List is Null .. can anyone tell the reason?
namespace UniversitySystem
{
class University : CollectionBase
{
private string _uniName;
Departments _depart = new Departments();
public University(string un, string dn, string cp, List<Student> Slist)
{
this._uniName = un;
this.CED.DepartName = dn;
this.CED.ChairPerson = cp;
foreach (Student s in Slist)
{
List.Add(s);
}
}
#region properties
public string UniName
{
get { return _uniName; }
set { _uniName = value; }
}
public Departments CED
{
get { return _depart; }
set { _depart = value; }
}
#endregion
public class Departments : CollectionBase
{
private string _departName;
public string DepartName
{
get { return _departName; }
set { _departName = value; }
}
private string _chairPerson;
public string ChairPerson
{
get { return _chairPerson; }
set { _chairPerson = value; }
}
public List<Student> StudentListForCED = new List<Student>();
public Departments()
{
_departName = null;
_chairPerson = null;
StudentListForCED = null;
}
public Departments(string dn, string cp, List<Student> Slist)
{
this._departName = dn;
this._chairPerson = cp;
foreach (Student s in Slist)
{
List.Add(s);
}
}
public void showDetails()
{
Console.WriteLine("Departmental Info");
Console.WriteLine("DepartmentName: " + _departName);
Console.WriteLine("Chairperson Name: " + _chairPerson);
Console.WriteLine("Student Info:");
foreach (Student item in List)
{
Console.WriteLine("Name: " + item.Name);
Console.WriteLine("deptName: " + item.RegNo);
Console.WriteLine("total marks: " + item.TotalMarksObtained);
Console.WriteLine("percentage: " + item.GetPercentage());
}
}
}
}
}
THE main() part is
namespace UniversitySystem
{
class Program
{
static void Main(string[] args)
{
List<Student> slist = new List<Student>();
slist.Add(new Student("sana", 1234, "CIS", 650));
slist.Add(new Student("anam", 2345, "BCIT", 400));
slist.Add(new Student("fizzza", 2670, "Electrical", 670));
University u1 = new University("NED", "computer", "UKP", slist);
Console.WriteLine(u1.CED.DepartName);
u1.CED.showDetails();
}
}
}
The initializing code for University does not store the list you give it as a parameter.
try storing the list in a variable in either the department or the university object itself, and when you are showing the details for either of those object you can reference that list, the one you stored upon creating the object.
Hope that helps!
I made a couple changes that should work.
public Departments(string dn, string cp, List<Student> Slist)
{
this._departName = dn;
this._chairPerson = cp;
foreach (Student s in Slist)
{
StudentListForCED.Add(s);
}
}
public void showDetails()
{
Console.WriteLine("Departmental Info");
Console.WriteLine("DepartmentName: " + _departName);
Console.WriteLine("Chairperson Name: " + _chairPerson);
Console.WriteLine("Student Info:");
foreach (Student item in StudentListForCED)
{
Console.WriteLine("Name: " + item.Name);
Console.WriteLine("deptName: " + item.RegNo);
Console.WriteLine("total marks: " + item.TotalMarksObtained);
Console.WriteLine("percentage: " + item.GetPercentage());
}
}
Please read this a little more thoroughly.