Created
May 12, 2019 22:45
-
-
Save flying3615/62a6b86b1141a695bf63049d07eb0234 to your computer and use it in GitHub Desktop.
Dirty check when inserting POJO into DB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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