Good point Dave. The problem is that (and Roger mentioned this somewhere) the db and hibernate metadata don't know that the "3" stored in a visit_attribute.value column is supposed to be FKd to location (or whatever).
One option is what Ben says: force all custom datatype handlers to use uuids. The other option would be that sync does a special-case for anything that implements CustomValue and whose typed value is an OpenmrsObject. (I can see how that would be able to convert *to* uuid when you record the changeset. But I don't know how you'd convert back from uuid when applying the changeset elsewhere.) How does sync currently handle things like global_property that frequently have ids stored as text? -Darius On Mon, Sep 26, 2011 at 11:33 AM, Ben Wolfe <[email protected]> wrote: > I'm pretty sure sync converts all person attributes to their uuid > equivalent already (and then back again). A similar thing could not be done > for handlers easily. However, if we suggested that all handlers use uuids > by default, then most would be ok. > > Ben > On Sep 26, 2011 8:48 PM, "Dave Thomas" <[email protected]> wrote: > > Hi. Sorry to jump into this late, but I'm concerned about this new > > attribute architecture with sync. > > > > If these custom handlers are serializing their objects using anything > > but uuids for openmrs objects, sync is going to propagate mangled > > data. That, or the custom handlers will have to be built into the > > sync serialization process somehow to make sure that openmrsObject > > references are uuid based. > > > > We get away with PersonAttributes at all currently because our > > location tables all look the same between parent and child servers, > > but in reality its already a precarious balance... > > > > d > > > > On Mon, Sep 26, 2011 at 5:56 AM, Burke Mamlin <[email protected]> > wrote: > >> I copied this e-mail onto this wiki page in case that helps anyone > (Roger) > >> in reviewing (commenting on) it. Anyone interested in this topic may > want > >> to watch that page as well as the associated ticket. > >> -Burke > >> > >> On Sat, Sep 24, 2011 at 4:03 PM, Darius Jazayeri <[email protected]> > >> wrote: > >>> > >>> Hi All, > >>> On our last few design calls we've been working through the generic > >>> AttributeType mechanism that we're introducing in 1.9. (see ticket) > >>> I wanted to summarize the current state of things. Some of this is in > >>> trunk, but some is refactoring I'm doing. I'm especially interested in > >>> thoughts about how these classes should be linked together with > >>> parameterized types, since I'm not convinced I've gotten that right: > >>> interface CustomDatatypeHandler<T> > >>> > >>> Capable of converting T to/from a String that can be persisted in the > >>> varchar column of a database. E.g. a date would be stored as yyyy-mm-dd > and > >>> an image might be stored as a uri pointing to a PACS system. Also > capable of > >>> validating T, e.g. so we can use a plain java.util.Date to represent > >>> "date-in-past" but limit its possible values. > >>> Defines a String "datatypeHandled", e.g. "date", > "regex-validated-string") > >>> T fromPersistedString(String) > >>> String toPersistedString(T) > >>> void validate(T) > >>> String render(String persistedValue, String view) > >>> can be configured with setHandlerConfiguration(String) > >>> > >>> interface CustomDatatyped > >>> > >>> holds the definition of a custom datatype (which is handled by a > handler > >>> of the above interface). For example VisitAttributeType and > GlobalProperty > >>> (we're able to do typed GPs trivially now) > >>> required: String getDatatype() > >>> optional: String getPreferredHandlerClassname() > >>> > >>> if specified, will be handled by this specific CustomDatatypeHandler, > >>> otherwise it will be handled by the default handler for this thing's > >>> datatype > >>> > >>> optional: String getHandlerConfig() > >>> > >>> interface AttributeType<OwningType extends Customizable> extends > >>> CustomDatatyped, OpenmrsMetadata > >>> > >>> for user-defined extensions to core domain objects, which would be > handled > >>> by adding custom database columns in a less generic system. E.g. > >>> VisitAttributeType implements AttributeType<Visit> > >>> datatype/handler specified via CustomDatatyped superinterface > >>> Integer getMinOccurs() > >>> Integer getMaxOccurs() > >>> > >>> class VisitAttributeType, class LocationAttributeType, class > >>> ProviderAttributeType > >>> > >>> trivial implementations of AttributeType (via BaseAttributeType) > >>> > >>> interface Customizable<AttrClass extends Attribute> > >>> > >>> Implemented by domain classes that may be customized by the user via > >>> custom attributes. E.g. Visit implements Customizable<VisitAttribute>, > >>> Location implements Customizable<LocationAttribute> > >>> Has convenience methods for dealing with a collection of attributes, of > >>> different types: > >>> Collection<AttrClass> getAttributes() //includes voided > >>> Collection<AttrClass> getActiveAttributes() //non-voided > >>> void addAttribute(AttrClass) > >>> void setAttribute(AttrClass) //voids other attributes of the given > type > >>> > >>> interface CustomValue > >>> > >>> holds a value managed by a CustomDatatypeHandler. E.g. VisitAttribute, > >>> GlobalProperty. Any implementation of this has a corresponding > >>> CustomDatatyped implementation. "persistedValue" is a String suitable > for > >>> persisting in a db varchar column; "objectValue" is what you'd want to > work > >>> with in the API. > >>> String getPersistedValue() > >>> void setPersistedValue() > >>> Object getObjectValue() // don't remember why this isn't <T> > >>> void setObjectValue(Object) > >>> > >>> interface Attribute<OwningType extends Customizable> implements > >>> CustomValue, OpenmrsData > >>> > >>> value corresponding to an AttributeType (which defines its datatype, > >>> whether it's required, whether it can repeat, etc), e.g. VisitAttribute > >>> corresponds to VisitAttributeType > >>> OwningType getOwner() > >>> void setOwner(OwningType) > >>> AttributeType<OwningType> getAttributeType() > >>> > >>> class VisitAttribute, class LocationAttribute, class ProviderAttribute > >>> > >>> trivial implementation of Attribute (via BaseAttribute) > >>> > >>> class GlobalProperty implements CustomDatatyped, CustomValue > >>> > >>> this is interesting in that it both defines a custom datatype and > stores > >>> its value > >>> > >>> Thoughts welcome... > >>> -Darius > >>> ________________________________ > >>> Click here to unsubscribe from OpenMRS Developers' mailing list > >> > >> ________________________________ > >> Click here to unsubscribe from OpenMRS Developers' mailing list > > > > _________________________________________ > > > > To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to > [email protected] with "SIGNOFF openmrs-devel-l" in the body > (not the subject) of your e-mail. > > > > [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l] > ------------------------------ > Click here to > unsubscribe<[email protected]?body=SIGNOFF%20openmrs-devel-l>from > OpenMRS Developers' mailing list > _________________________________________ To unsubscribe from OpenMRS Developers' mailing list, send an e-mail to [email protected] with "SIGNOFF openmrs-devel-l" in the body (not the subject) of your e-mail. [mailto:[email protected]?body=SIGNOFF%20openmrs-devel-l]

