Skip to content

Instantly share code, notes, and snippets.

@flying3615
Created May 12, 2019 22:45
Show Gist options
  • Save flying3615/62a6b86b1141a695bf63049d07eb0234 to your computer and use it in GitHub Desktop.
Save flying3615/62a6b86b1141a695bf63049d07eb0234 to your computer and use it in GitHub Desktop.
Dirty check when inserting POJO into DB
//Anotation for fields need to check
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ModifiableField {
}
public abstract class PersistedObject {
public static final long UNSET_PRIMARY_KEY = 0L;
protected long primaryKey = UNSET_PRIMARY_KEY;
public PersistedObject() {
}
public long getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(long primaryKey) {
this.primaryKey = primaryKey;
}
public void blankPrimaryKey() {
primaryKey = UNSET_PRIMARY_KEY;
}
public boolean inDatabase() {
return primaryKey != UNSET_PRIMARY_KEY;
}
}
/**
* ModifiableObject with ModifiableField need to be checked if it's drity
*/
public class ModifiableObject extends PersistedObject {
private boolean dirty = false;
private Map<String, Field> modifiableFields = new HashMap<>();
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean dirty) {
this.dirty = dirty;
}
public ModifiableObject() {
getModifiableFields();
}
protected boolean setPersistedField(String fieldName, Object newValue) {
boolean changed = false;
Field field = modifiableFields.get(fieldName);
if (field == null) {
throw new IllegalArgumentException("Field " + fieldName + " is not persisted for class" + getClass().getCanonicalName());
}
try {
Object currentValue = field.get(this);
if (currentValue == null && newValue != null || currentValue != null && !currentValue.equals(newValue)) {
this.dirty = true;
changed = true;
}
field.set(this, newValue);
} catch (Exception e) {
throw new IllegalStateException("Could not modify field " + fieldName, e);
}
return changed;
}
private void getModifiableFields() {
List<Field> allFields = new ArrayList<>();
getAllFields(allFields, this.getClass());
for (Field field : allFields) {
if (field.getAnnotation(ModifiableField.class) != null) {
field.setAccessible(true);
modifiableFields.put(field.getName(), field);
}
}
}
private static void getAllFields(List<Field> fields, Class<?> type) {
fields.addAll(Arrays.asList(type.getDeclaredFields()));
if (type.getSuperclass() != null) {
getAllFields(fields, type.getSuperclass());
}
}
}
//----------POJO--------------
public static class Meeting extends ModifiableObject {
@ModifiableField
private LocalDate meetingDate;
@ModifiableField
private String trackCondition;
Getter, Setter toString...
}
//-------Service------
@Service
public class CanonicalServiceImpl implements CanonicalService {
@Autowired
private MeetingDAO meetingDAO;
@Override
public void saveMeeting(Meeting meeting) {
if (meeting == null) {
throw new IllegalArgumentException("Must provide a non-null meeting");
}
if (meeting.inDatabase()) {
if (meeting.isDirty()) {
meetingDAO.update(meeting);
}
} else {
meetingDAO.insert(meeting);
}
}
}
//---------DAO---------
@Repository
public class MybatisMeetingDAO implements MeetingDAO {
@Override
public Meeting insert(Meeting meeting) {
MeetingStub stub = new MeetingStub(meeting, gson.toJson(meeting));
mapper.insertMeeting(stub);
meeting.setPrimaryKey(stub.getMeetingId());
meeting.setDirty(false);
return meeting;
}
@Override
public Meeting update(Meeting meeting) {
MeetingStub stub = new MeetingStub(meeting, gson.toJson(meeting));
mapper.updateMeeting(stub);
meeting.setDirty(false);
return meeting;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment