You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@isis.apache.org by Stephen Cameron <st...@gmail.com> on 2015/11/25 21:25:19 UTC
Application Tenancy
Hi,
I have a problem with Application Tenancies not working the way I want, I
want to drive it off a field 'region', such that a person is assigned a
tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the regions
that they are working in too, so when they create a record their region
gets assigned to the new record and that controls who else can see the
record.
This mostly works, but there is one small glitch. The main problem I have
is setting it up so that region is non-null and any records created by a
GLOBAL tenancy user are seen by all users, while those created by a NORTH,
SOUTH or NORTH-WEST user are seen only by users with the same tenancy. By
changing the region of a record it can change tenancy.
Presently this is broken, or at least it I think it was working correctly
when I allowed a record with a region of null to be the GLOBAL ones. I need
to have this working for a demo tomorrow, so advice is welcomed on how best
to set this up properly.
My base class that controls all this here:
https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
The other small glitch is that a person record created in the process of
creating a participant doesn't get assigned a region automatically. I have
a work-around for that in place at present, anything that has a null region
gets presented as having a global tenancy.
Thanks
Steve Cameron
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
True, I created the error by tidying my code!
The current set of issues has been thrown up by removing some TODOs one of
which was to improve the compareTo() by adding in region to the list of
compare fields.
I have another one to sort out now.
On Thu, Nov 26, 2015 at 9:10 PM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:
> Might be worth using Project Lombok, then... less boilerplate so easier to
> spot such issues.
>
>
> http://isis.apache.org/guides/cg.html#_cg_ide_project-lombok
>
>
> On 26 November 2015 at 10:08, Stephen Cameron <st...@gmail.com>
> wrote:
>
> > Yes, I still had a variable region declared in Person that was
> over-riding
> > the one in the base class I guess, so the setter was setting the super
> > class but the subclass value was being persisted.
> >
> > On Thu, Nov 26, 2015 at 8:45 PM, Stephen Cameron <
> > steve.cameron.62@gmail.com
> > > wrote:
> >
> > > My silly mistake!
> > >
> > > On Thu, Nov 26, 2015 at 8:40 PM, Stephen Cameron <
> > > steve.cameron.62@gmail.com> wrote:
> > >
> > >> That is not the problem then,
> > >>
> > >> Its a bit bizarre actually, I generated some logging and added some
> > >> messages, I see that two objects Participation and Participant do have
> > >> their region value set but the Person object doesn't.
> > >>
> > >> All these objects extend the same base class, but the SQL insert
> > created
> > >> for Person doesn't have the value whereas it does for the others.
> > >>
> > >> The code is as follows:
> > >>
> > >> @Programmatic
> > >> public void setUpdatedBy(String updatedBy) {
> > >> if (getCreatedBy() == null) {
> > >> setCreatedBy(updatedBy);
> > >> System.out.println(">>>updatedBy: " + updatedBy);
> > >> if (userRepository != null) {
> > >> System.out.println(">>>repositoryExists");
> > >> ApplicationUser user =
> > >> userRepository.findByUsername(updatedBy);
> > >> if (user != null && user.getTenancy() != null) {
> > >> String path = user.getTenancy().getPath();
> > >> String name =
> path.substring(path.lastIndexOf("/") +
> > >> 1);
> > >> if (name.isEmpty())
> > >> name = "GLOBAL";
> > >> System.out.println(">>>setting Region for name: "
> +
> > >> name);
> > >> setRegion(regions.regionForName(name));
> > >> }else{
> > >> System.out.println(">>>>user tenancy not found");
> > >> setRegion(regions.regionForName("GLOBAL")); //TODO
> > >> temp fix
> > >> }
> > >> }
> > >> else{
> > >> System.out.println(">>>userRepository is null");
> > >> setRegion(regions.regionForName("GLOBAL")); //TODO
> temp
> > >> fix
> > >> }
> > >> } else
> > >> setLastModifiedBy(updatedBy);
> > >> }
> > >>
> > >> The stdout:
> > >>
> > >>
> > >> 20:20:25,720 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'au.com.scds.chats.dom.module.general.Person' AS
> > >>
> >
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.birthdate,a0.email,a0.emailaddress,a0.firstname,a0.homephonenumber,a0.middlename,a0.mobilephonenumber,a0.oldid,a0.preferredname,a0.surname,a0.person_id
> > >> FROM person a0 WHERE a0.surname = <'Ncks'>
> > >> >>>updatedBy: sven
> > >> >>>repositoryExists
> > >> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> > >> "
> > >> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> > >> "
> > >> 20:20:25,732 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> > >>
> >
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> > >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> > >> >>>setting Region for name: GLOBAL
> > >> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> > >> "
> > >> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> > >> "
> > >> 20:20:25,738 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> > >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> > >> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,792 [Native qtp209845522-18 DEBUG] INSERT
> INTO
> > >> person
> > >>
> >
> (birthdate,contacttype_name,email,emailaddress,englishskill_englishskill_id,firstname,homephonenumber,mailaddress_location_id,middlename,mobilephonenumber,oldid,preferredname,region_name,salutation_name,streetaddress_location_id,surname,createdby,createdon,lastmodifiedby,lastmodifiedon)
> > >> VALUES
> > >>
> >
> (<1960-10-19>,<null>,<null>,<null>,<null>,<'Stevie'>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<'Nicks'>,<'sven'>,<2015-11-26
> > >> 20:20:25.74>,<null>,<null>)
> > >> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> > >> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> > >> >>>updatedBy: sven
> > >> >>>repositoryExists
> > >> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> > >> "
> > >> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> > >> "
> > >> 20:20:25,809 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> > >>
> >
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> > >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> > >> >>>setting Region for name: GLOBAL
> > >> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> > >> "
> > >> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> > >> "
> > >> 20:20:25,812 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> > >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> > >> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,816 [Native qtp209845522-18 DEBUG] INSERT
> INTO
> > >> participant
> > >>
> >
> (lifehistory_lifehistory_id,loneliness_loneliness_id,person_person_id,socialfactors_socialfactors_id,status,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> > >> VALUES (<null>,<null>,<8>,<null>,<'ACTIVE'>,<'sven'>,<2015-11-26
> > >> 20:20:25.814>,<null>,<null>,<'GLOBAL'>)
> > >> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> > >> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> > >> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> > >> "
> > >> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> > >> "
> > >> 20:20:25,826 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'au.com.scds.chats.dom.module.participant.Participation' AS
> > >>
> >
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.dropofftime,a0.oldid,a0.pickuptime,a0.roleid,a0.transportnotes,a0.participation_id
> > >> FROM participation a0 WHERE a0.activity_activity_id = <1>
> > >> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> > >> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> > >> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> > >> "
> > >> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> > >> "
> > >> 20:20:25,832 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> > >> FROM participation a0 INNER JOIN activity b0 ON
> a0.activity_activity_id
> > =
> > >> b0.activity_id WHERE a0.participation_id = <3>
> > >> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> > >> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> > >> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> > >> "
> > >> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> > >> "
> > >> 20:20:25,837 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> > >> FROM participation a0 INNER JOIN participant b0 ON
> > >> a0.participant_participant_id = b0.participant_id WHERE
> > a0.participation_id
> > >> = <3>
> > >> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> > >> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> > >> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> > >> "
> > >> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> > >> "
> > >> 20:20:25,840 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> > >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> > >> b0.person_id WHERE a0.participant_id = <3>
> > >> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> > >> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> > >> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> > >> "
> > >> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> > >> "
> > >> 20:20:25,844 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> > >> FROM participation a0 INNER JOIN activity b0 ON
> a0.activity_activity_id
> > =
> > >> b0.activity_id WHERE a0.participation_id = <6>
> > >> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> > >> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> > >> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> > >> "
> > >> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> > >> "
> > >> 20:20:25,846 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> > >> FROM participation a0 INNER JOIN participant b0 ON
> > >> a0.participant_participant_id = b0.participant_id WHERE
> > a0.participation_id
> > >> = <6>
> > >> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> > >> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> > >> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> > >> "
> > >> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> > >> "
> > >> 20:20:25,849 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> > >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> > >> b0.person_id WHERE a0.participant_id = <6>
> > >> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> > >> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> > >> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> > >> "
> > >> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> > >> "
> > >> 20:20:25,854 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> > >> FROM participation a0 INNER JOIN activity b0 ON
> a0.activity_activity_id
> > =
> > >> b0.activity_id WHERE a0.participation_id = <7>
> > >> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> > >> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> > >> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> > >> "
> > >> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> > >> "
> > >> 20:20:25,856 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> > >> FROM participation a0 INNER JOIN participant b0 ON
> > >> a0.participant_participant_id = b0.participant_id WHERE
> > a0.participation_id
> > >> = <7>
> > >> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> > >> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> > >> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> > >> "
> > >> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> > >> "
> > >> 20:20:25,859 [Native qtp209845522-18 DEBUG] SELECT
> > >>
> >
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> > >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> > >> b0.person_id WHERE a0.participant_id = <7>
> > >> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> > >> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> > >> >>>updatedBy: sven
> > >> >>>repositoryExists
> > >> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> > >> "
> > >> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> > >> "
> > >> 20:20:25,871 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> > >>
> >
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> > >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> > >> >>>setting Region for name: GLOBAL
> > >> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> > >> "
> > >> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> > >> PreparedStatement
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> > >> "
> > >> 20:20:25,881 [Native qtp209845522-18 DEBUG] SELECT
> > >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> > >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> > >> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> > >> PreparedStatement
> > >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673"
> > for
> > >> connection
> > >>
> >
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> > >> "
> > >> 20:20:25,886 [Native qtp209845522-18 DEBUG] INSERT
> INTO
> > >> participation
> > >>
> >
> (activity_activity_id,arrivingtransporttype_name,departingtransporttype_name,dropofftime,oldid,participant_participant_id,pickuptime,roleid,transportnotes,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> > >> VALUES
> > >>
> >
> (<1>,<null>,<null>,<null>,<null>,<8>,<null>,<null>,<null>,<'sven'>,<2015-11-26
> > >> 20:20:25.883>,<null>,<null>,<'GLOBAL'>)
> > >>
> > >>
> > >> On Thu, Nov 26, 2015 at 8:11 PM, Dan Haywood <
> > >> dan@haywood-associates.co.uk> wrote:
> > >>
> > >>> If you just new them up:
> > >>>
> > >>> Customer cust = new Customer();
> > >>>
> > >>> then the framework doesn't know about it and any services will be
> null.
> > >>>
> > >>> You can then use:
> > >>>
> > >>> domainObjectContainer.injectServicesInto(cust);
> > >>>
> > >>> ~~~
> > >>>
> > >>> Alternatively, use:
> > >>>
> > >>> Customer cust = container.newTransientInstance(Customer.class);
> > >>>
> > >>> to do both steps in one.
> > >>>
> > >>> HTH
> > >>> Dan
> > >>>
> > >>>
> > >>> On 26 November 2015 at 09:09, Stephen Cameron <
> > >>> steve.cameron.62@gmail.com>
> > >>> wrote:
> > >>>
> > >>> > Hi,
> > >>> >
> > >>> > I think I've read somewhere that domain services aren't always
> > injected
> > >>> > into entities by default and you sometimes have to trigger this
> > >>> yourself?
> > >>> >
> > >>> > Is this a correct?
> > >>> >
> > >>> > Thank
> > >>> >
> > >>> >
> > >>> > On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
> > >>> > steve.cameron.62@gmail.com> wrote:
> > >>> >
> > >>> > > I cannot try alternatives till later this evening, will let you
> > know
> > >>> > > of results. If I cannot get tenancies working for tomorrow its
> not
> > >>> the
> > >>> > end
> > >>> > > of the world. I was getting "record not found" errors last night
> > due
> > >>> to
> > >>> > > making region allowsNull="false", so a bit of a panic, given its
> > >>> > > mostly been working very smoothly now for a while.
> > >>> > >
> > >>> > > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
> > >>> > dan@haywood-associates.co.uk
> > >>> > > > wrote:
> > >>> > >
> > >>> > >> On 25 November 2015 at 22:26, Stephen Cameron <
> > >>> > steve.cameron.62@gmail.com
> > >>> > >> >
> > >>> > >> wrote:
> > >>> > >>
> > >>> > >> > Hi Dan,
> > >>> > >> >
> > >>> > >> > I did not explain it that well sorry.
> > >>> > >> >
> > >>> > >> > I want to get rid of nulls completely, the fact that I do
> handle
> > >>> them
> > >>> > is
> > >>> > >> > just a work-around for the fact that they are still being
> > >>> created, but
> > >>> > >> only
> > >>> > >> > for People. That is, if a new Participant is registered it
> looks
> > >>> to
> > >>> > see
> > >>> > >> if
> > >>> > >> > there is an existing Person with the same details then adds a
> > new
> > >>> one
> > >>> > if
> > >>> > >> > not present (a single Person can be a Participant and/or a
> > >>> Volunteer).
> > >>> > >> The
> > >>> > >> > Participant is getting its region set in setUpdatedBy() but
> the
> > >>> Person
> > >>> > >> is
> > >>> > >> > not, I need to debug this.
> > >>> > >> >
> > >>> > >> >
> > >>> > >> In 1.10.0, a better approach is probably to add a subscriber to
> > the
> > >>> > >> lifecycle events:
> > >>> > >>
> > >>> > >> @DomainService(nature=NatureOfService.DOMAIN)
> > >>> > >> public class RegionSubscriber extends AbstractSubscriber {
> > >>> > >>
> > >>> > >> @Subscribe
> > >>> > >> public void on(ObjectPersistingEvent ev) {
> > >>> > >> Object domainObject = ev.getSource();
> > >>> > >> }
> > >>> > >>
> > >>> > >> @Subscribe
> > >>> > >> public void on(ObjectUpdatingEvent ev) {
> > >>> > >> Object domainObject = ev.getSource();
> > >>> > >> }
> > >>> > >> }
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >> > As general interest is handling such things via such a service
> > >>> better,
> > >>> > >> that
> > >>> > >> > is to avoid injecting services into entities if possible?
> > >>> > >> >
> > >>> > >> >
> > >>> > >> There's nothing wrong with injecting services into entities; it
> > >>> allows
> > >>> > >> them
> > >>> > >> to perform their responsibilities without leaking details of how
> > >>> they do
> > >>> > >> it
> > >>> > >> (their implementation) to the caller. I don't hold by this
> "pass
> > >>> in the
> > >>> > >> services" and "double dispatch"... I see that as a code smell.
> > >>> > >>
> > >>> > >> On the other hand, we now have a very rich set of domain events;
> > in
> > >>> AOP
> > >>> > >> terms these are jointpoints (or is it pointcuts? see [1]),
> anyway
> > >>> they
> > >>> > are
> > >>> > >> a different way to cause "stuff to happen".
> > >>> > >>
> > >>> > >> Should one have the entity call a services, or rely on
> subscribers
> > >>> to
> > >>> > >> domain events? With the latter, the entity is very clean and
> the
> > >>> > >> responsibility kept completely separate. On the other hand,
> with
> > >>> events
> > >>> > >> the order in which the subscribers fire is non-deterministic.
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >> > Last minute tweeks aren't the best idea, but the tests that I
> do
> > >>> have
> > >>> > >> are
> > >>> > >> > proving their value. These particular issues are probably a
> > >>> result of
> > >>> > no
> > >>> > >> > integration tests yet.
> > >>> > >> >
> > >>> > >> >
> > >>> > >> It's not clear to me if my suggestion to use the
> TenancyEvaluator
> > >>> SPI
> > >>> > >> helped ? Or, indeed, whether you have a reasonable workaround
> in
> > >>> your
> > >>> > >> current handling of the nulls?
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >>
> > >>> > >> > Thanks
> > >>> > >> >
> > >>> > >> >
> > >>> > >>
> > >>> > >> [1]
> > >>> > >>
> > >>> > >>
> > >>> >
> > >>>
> >
> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
> > >>> > >>
> > >>> > >>
> > >>> > >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
> > >>> > >> dan@haywood-associates.co.uk
> > >>> > >> > >
> > >>> > >> > wrote:
> > >>> > >> >
> > >>> > >> > > Hi Steve,
> > >>> > >> > >
> > >>> > >> > > Not sure I follow quite all the ins-and-outs of this, but
> what
> > >>> could
> > >>> > >> well
> > >>> > >> > > be of use is the optional ApplicationTenancyPathEvaluator
> > domain
> > >>> > >> > > service[1]. If an implementation is registered (on the
> > >>> classpath),
> > >>> > >> then
> > >>> > >> > > the security module will delegate to this [2] in order to
> > >>> determine
> > >>> > >> who
> > >>> > >> > > gets to see/edit what.
> > >>> > >> > >
> > >>> > >> > > From what I did follow, it sounds like you need to treat
> > objects
> > >>> > with
> > >>> > >> a
> > >>> > >> > > null region in a particular way? If so, then hopefully you
> can
> > >>> put
> > >>> > >> this
> > >>> > >> > > "special case" logic in an implementation of said service.
> > >>> > >> > >
> > >>> > >> > > HTH
> > >>> > >> > > Dan
> > >>> > >> > >
> > >>> > >> > >
> > >>> > >> > >
> > >>> > >> > > [1]
> > >>> > >> > >
> > >>> > >> > >
> > >>> > >> >
> > >>> > >>
> > >>> >
> > >>>
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> > >>> > >> > > [2]
> > >>> > >> > >
> > >>> > >> > >
> > >>> > >> >
> > >>> > >>
> > >>> >
> > >>>
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> > >>> > >> > >
> > >>> > >> > >
> > >>> > >> > > On 25 November 2015 at 20:25, Stephen Cameron <
> > >>> > >> > steve.cameron.62@gmail.com>
> > >>> > >> > > wrote:
> > >>> > >> > >
> > >>> > >> > > > Hi,
> > >>> > >> > > >
> > >>> > >> > > > I have a problem with Application Tenancies not working
> the
> > >>> way I
> > >>> > >> > want, I
> > >>> > >> > > > want to drive it off a field 'region', such that a person
> is
> > >>> > >> assigned a
> > >>> > >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are
> > >>> also the
> > >>> > >> > > regions
> > >>> > >> > > > that they are working in too, so when they create a record
> > >>> their
> > >>> > >> region
> > >>> > >> > > > gets assigned to the new record and that controls who else
> > >>> can see
> > >>> > >> the
> > >>> > >> > > > record.
> > >>> > >> > > >
> > >>> > >> > > > This mostly works, but there is one small glitch. The main
> > >>> > problem I
> > >>> > >> > have
> > >>> > >> > > > is setting it up so that region is non-null and any
> records
> > >>> > created
> > >>> > >> by
> > >>> > >> > a
> > >>> > >> > > > GLOBAL tenancy user are seen by all users, while those
> > >>> created by
> > >>> > a
> > >>> > >> > > NORTH,
> > >>> > >> > > > SOUTH or NORTH-WEST user are seen only by users with the
> > same
> > >>> > >> tenancy.
> > >>> > >> > By
> > >>> > >> > > > changing the region of a record it can change tenancy.
> > >>> > >> > > >
> > >>> > >> > > > Presently this is broken, or at least it I think it was
> > >>> working
> > >>> > >> > correctly
> > >>> > >> > > > when I allowed a record with a region of null to be the
> > GLOBAL
> > >>> > >> ones. I
> > >>> > >> > > need
> > >>> > >> > > > to have this working for a demo tomorrow, so advice is
> > >>> welcomed on
> > >>> > >> how
> > >>> > >> > > best
> > >>> > >> > > > to set this up properly.
> > >>> > >> > > >
> > >>> > >> > > > My base class that controls all this here:
> > >>> > >> > > >
> > >>> > >> > > >
> > >>> > >> > >
> > >>> > >> >
> > >>> > >>
> > >>> >
> > >>>
> >
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> > >>> > >> > > >
> > >>> > >> > > > The other small glitch is that a person record created in
> > the
> > >>> > >> process
> > >>> > >> > of
> > >>> > >> > > > creating a participant doesn't get assigned a region
> > >>> > automatically.
> > >>> > >> I
> > >>> > >> > > have
> > >>> > >> > > > a work-around for that in place at present, anything that
> > has
> > >>> a
> > >>> > null
> > >>> > >> > > region
> > >>> > >> > > > gets presented as having a global tenancy.
> > >>> > >> > > >
> > >>> > >> > > >
> > >>> > >> > > > Thanks
> > >>> > >> > > >
> > >>> > >> > > > Steve Cameron
> > >>> > >> > > >
> > >>> > >> > >
> > >>> > >> >
> > >>> > >>
> > >>> > >
> > >>> > >
> > >>> >
> > >>>
> > >>
> > >>
> > >
> >
>
Re: Application Tenancy
Posted by Dan Haywood <da...@haywood-associates.co.uk>.
Might be worth using Project Lombok, then... less boilerplate so easier to
spot such issues.
http://isis.apache.org/guides/cg.html#_cg_ide_project-lombok
On 26 November 2015 at 10:08, Stephen Cameron <st...@gmail.com>
wrote:
> Yes, I still had a variable region declared in Person that was over-riding
> the one in the base class I guess, so the setter was setting the super
> class but the subclass value was being persisted.
>
> On Thu, Nov 26, 2015 at 8:45 PM, Stephen Cameron <
> steve.cameron.62@gmail.com
> > wrote:
>
> > My silly mistake!
> >
> > On Thu, Nov 26, 2015 at 8:40 PM, Stephen Cameron <
> > steve.cameron.62@gmail.com> wrote:
> >
> >> That is not the problem then,
> >>
> >> Its a bit bizarre actually, I generated some logging and added some
> >> messages, I see that two objects Participation and Participant do have
> >> their region value set but the Person object doesn't.
> >>
> >> All these objects extend the same base class, but the SQL insert
> created
> >> for Person doesn't have the value whereas it does for the others.
> >>
> >> The code is as follows:
> >>
> >> @Programmatic
> >> public void setUpdatedBy(String updatedBy) {
> >> if (getCreatedBy() == null) {
> >> setCreatedBy(updatedBy);
> >> System.out.println(">>>updatedBy: " + updatedBy);
> >> if (userRepository != null) {
> >> System.out.println(">>>repositoryExists");
> >> ApplicationUser user =
> >> userRepository.findByUsername(updatedBy);
> >> if (user != null && user.getTenancy() != null) {
> >> String path = user.getTenancy().getPath();
> >> String name = path.substring(path.lastIndexOf("/") +
> >> 1);
> >> if (name.isEmpty())
> >> name = "GLOBAL";
> >> System.out.println(">>>setting Region for name: " +
> >> name);
> >> setRegion(regions.regionForName(name));
> >> }else{
> >> System.out.println(">>>>user tenancy not found");
> >> setRegion(regions.regionForName("GLOBAL")); //TODO
> >> temp fix
> >> }
> >> }
> >> else{
> >> System.out.println(">>>userRepository is null");
> >> setRegion(regions.regionForName("GLOBAL")); //TODO temp
> >> fix
> >> }
> >> } else
> >> setLastModifiedBy(updatedBy);
> >> }
> >>
> >> The stdout:
> >>
> >>
> >> 20:20:25,720 [Native qtp209845522-18 DEBUG] SELECT
> >> 'au.com.scds.chats.dom.module.general.Person' AS
> >>
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.birthdate,a0.email,a0.emailaddress,a0.firstname,a0.homephonenumber,a0.middlename,a0.mobilephonenumber,a0.oldid,a0.preferredname,a0.surname,a0.person_id
> >> FROM person a0 WHERE a0.surname = <'Ncks'>
> >> >>>updatedBy: sven
> >> >>>repositoryExists
> >> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> >> "
> >> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> >> "
> >> 20:20:25,732 [Native qtp209845522-18 DEBUG] SELECT
> >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> >>
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >> >>>setting Region for name: GLOBAL
> >> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> >> "
> >> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> >> "
> >> 20:20:25,738 [Native qtp209845522-18 DEBUG] SELECT
> >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> >> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,792 [Native qtp209845522-18 DEBUG] INSERT INTO
> >> person
> >>
> (birthdate,contacttype_name,email,emailaddress,englishskill_englishskill_id,firstname,homephonenumber,mailaddress_location_id,middlename,mobilephonenumber,oldid,preferredname,region_name,salutation_name,streetaddress_location_id,surname,createdby,createdon,lastmodifiedby,lastmodifiedon)
> >> VALUES
> >>
> (<1960-10-19>,<null>,<null>,<null>,<null>,<'Stevie'>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<'Nicks'>,<'sven'>,<2015-11-26
> >> 20:20:25.74>,<null>,<null>)
> >> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> >> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> >> >>>updatedBy: sven
> >> >>>repositoryExists
> >> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> >> "
> >> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> >> "
> >> 20:20:25,809 [Native qtp209845522-18 DEBUG] SELECT
> >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> >>
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >> >>>setting Region for name: GLOBAL
> >> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> >> "
> >> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> >> "
> >> 20:20:25,812 [Native qtp209845522-18 DEBUG] SELECT
> >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> >> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,816 [Native qtp209845522-18 DEBUG] INSERT INTO
> >> participant
> >>
> (lifehistory_lifehistory_id,loneliness_loneliness_id,person_person_id,socialfactors_socialfactors_id,status,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> >> VALUES (<null>,<null>,<8>,<null>,<'ACTIVE'>,<'sven'>,<2015-11-26
> >> 20:20:25.814>,<null>,<null>,<'GLOBAL'>)
> >> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> >> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> >> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> >> "
> >> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> >> "
> >> 20:20:25,826 [Native qtp209845522-18 DEBUG] SELECT
> >> 'au.com.scds.chats.dom.module.participant.Participation' AS
> >>
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.dropofftime,a0.oldid,a0.pickuptime,a0.roleid,a0.transportnotes,a0.participation_id
> >> FROM participation a0 WHERE a0.activity_activity_id = <1>
> >> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> >> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> >> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> >> "
> >> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> >> "
> >> 20:20:25,832 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> >> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id
> =
> >> b0.activity_id WHERE a0.participation_id = <3>
> >> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> >> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> >> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> >> "
> >> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> >> "
> >> 20:20:25,837 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> >> FROM participation a0 INNER JOIN participant b0 ON
> >> a0.participant_participant_id = b0.participant_id WHERE
> a0.participation_id
> >> = <3>
> >> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> >> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> >> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> >> "
> >> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> >> "
> >> 20:20:25,840 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> >> b0.person_id WHERE a0.participant_id = <3>
> >> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> >> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> >> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> >> "
> >> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> >> "
> >> 20:20:25,844 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> >> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id
> =
> >> b0.activity_id WHERE a0.participation_id = <6>
> >> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> >> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> >> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> >> "
> >> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> >> "
> >> 20:20:25,846 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> >> FROM participation a0 INNER JOIN participant b0 ON
> >> a0.participant_participant_id = b0.participant_id WHERE
> a0.participation_id
> >> = <6>
> >> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> >> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> >> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> >> "
> >> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> >> "
> >> 20:20:25,849 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> >> b0.person_id WHERE a0.participant_id = <6>
> >> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> >> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> >> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> >> "
> >> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> >> "
> >> 20:20:25,854 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> >> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id
> =
> >> b0.activity_id WHERE a0.participation_id = <7>
> >> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> >> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> >> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> >> "
> >> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> >> "
> >> 20:20:25,856 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> >> FROM participation a0 INNER JOIN participant b0 ON
> >> a0.participant_participant_id = b0.participant_id WHERE
> a0.participation_id
> >> = <7>
> >> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> >> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> >> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> >> "
> >> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> >> "
> >> 20:20:25,859 [Native qtp209845522-18 DEBUG] SELECT
> >>
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> >> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> >> b0.person_id WHERE a0.participant_id = <7>
> >> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> >> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> >> >>>updatedBy: sven
> >> >>>repositoryExists
> >> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> >> "
> >> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> >> "
> >> 20:20:25,871 [Native qtp209845522-18 DEBUG] SELECT
> >> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> >>
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> >> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >> >>>setting Region for name: GLOBAL
> >> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> >> "
> >> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> >> PreparedStatement
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> >> "
> >> 20:20:25,881 [Native qtp209845522-18 DEBUG] SELECT
> >> 'au.com.scds.chats.dom.module.general.names.Region' AS
> >> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> >> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> >> PreparedStatement
> >> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673"
> for
> >> connection
> >>
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> >> "
> >> 20:20:25,886 [Native qtp209845522-18 DEBUG] INSERT INTO
> >> participation
> >>
> (activity_activity_id,arrivingtransporttype_name,departingtransporttype_name,dropofftime,oldid,participant_participant_id,pickuptime,roleid,transportnotes,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> >> VALUES
> >>
> (<1>,<null>,<null>,<null>,<null>,<8>,<null>,<null>,<null>,<'sven'>,<2015-11-26
> >> 20:20:25.883>,<null>,<null>,<'GLOBAL'>)
> >>
> >>
> >> On Thu, Nov 26, 2015 at 8:11 PM, Dan Haywood <
> >> dan@haywood-associates.co.uk> wrote:
> >>
> >>> If you just new them up:
> >>>
> >>> Customer cust = new Customer();
> >>>
> >>> then the framework doesn't know about it and any services will be null.
> >>>
> >>> You can then use:
> >>>
> >>> domainObjectContainer.injectServicesInto(cust);
> >>>
> >>> ~~~
> >>>
> >>> Alternatively, use:
> >>>
> >>> Customer cust = container.newTransientInstance(Customer.class);
> >>>
> >>> to do both steps in one.
> >>>
> >>> HTH
> >>> Dan
> >>>
> >>>
> >>> On 26 November 2015 at 09:09, Stephen Cameron <
> >>> steve.cameron.62@gmail.com>
> >>> wrote:
> >>>
> >>> > Hi,
> >>> >
> >>> > I think I've read somewhere that domain services aren't always
> injected
> >>> > into entities by default and you sometimes have to trigger this
> >>> yourself?
> >>> >
> >>> > Is this a correct?
> >>> >
> >>> > Thank
> >>> >
> >>> >
> >>> > On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
> >>> > steve.cameron.62@gmail.com> wrote:
> >>> >
> >>> > > I cannot try alternatives till later this evening, will let you
> know
> >>> > > of results. If I cannot get tenancies working for tomorrow its not
> >>> the
> >>> > end
> >>> > > of the world. I was getting "record not found" errors last night
> due
> >>> to
> >>> > > making region allowsNull="false", so a bit of a panic, given its
> >>> > > mostly been working very smoothly now for a while.
> >>> > >
> >>> > > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
> >>> > dan@haywood-associates.co.uk
> >>> > > > wrote:
> >>> > >
> >>> > >> On 25 November 2015 at 22:26, Stephen Cameron <
> >>> > steve.cameron.62@gmail.com
> >>> > >> >
> >>> > >> wrote:
> >>> > >>
> >>> > >> > Hi Dan,
> >>> > >> >
> >>> > >> > I did not explain it that well sorry.
> >>> > >> >
> >>> > >> > I want to get rid of nulls completely, the fact that I do handle
> >>> them
> >>> > is
> >>> > >> > just a work-around for the fact that they are still being
> >>> created, but
> >>> > >> only
> >>> > >> > for People. That is, if a new Participant is registered it looks
> >>> to
> >>> > see
> >>> > >> if
> >>> > >> > there is an existing Person with the same details then adds a
> new
> >>> one
> >>> > if
> >>> > >> > not present (a single Person can be a Participant and/or a
> >>> Volunteer).
> >>> > >> The
> >>> > >> > Participant is getting its region set in setUpdatedBy() but the
> >>> Person
> >>> > >> is
> >>> > >> > not, I need to debug this.
> >>> > >> >
> >>> > >> >
> >>> > >> In 1.10.0, a better approach is probably to add a subscriber to
> the
> >>> > >> lifecycle events:
> >>> > >>
> >>> > >> @DomainService(nature=NatureOfService.DOMAIN)
> >>> > >> public class RegionSubscriber extends AbstractSubscriber {
> >>> > >>
> >>> > >> @Subscribe
> >>> > >> public void on(ObjectPersistingEvent ev) {
> >>> > >> Object domainObject = ev.getSource();
> >>> > >> }
> >>> > >>
> >>> > >> @Subscribe
> >>> > >> public void on(ObjectUpdatingEvent ev) {
> >>> > >> Object domainObject = ev.getSource();
> >>> > >> }
> >>> > >> }
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >> > As general interest is handling such things via such a service
> >>> better,
> >>> > >> that
> >>> > >> > is to avoid injecting services into entities if possible?
> >>> > >> >
> >>> > >> >
> >>> > >> There's nothing wrong with injecting services into entities; it
> >>> allows
> >>> > >> them
> >>> > >> to perform their responsibilities without leaking details of how
> >>> they do
> >>> > >> it
> >>> > >> (their implementation) to the caller. I don't hold by this "pass
> >>> in the
> >>> > >> services" and "double dispatch"... I see that as a code smell.
> >>> > >>
> >>> > >> On the other hand, we now have a very rich set of domain events;
> in
> >>> AOP
> >>> > >> terms these are jointpoints (or is it pointcuts? see [1]), anyway
> >>> they
> >>> > are
> >>> > >> a different way to cause "stuff to happen".
> >>> > >>
> >>> > >> Should one have the entity call a services, or rely on subscribers
> >>> to
> >>> > >> domain events? With the latter, the entity is very clean and the
> >>> > >> responsibility kept completely separate. On the other hand, with
> >>> events
> >>> > >> the order in which the subscribers fire is non-deterministic.
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >> > Last minute tweeks aren't the best idea, but the tests that I do
> >>> have
> >>> > >> are
> >>> > >> > proving their value. These particular issues are probably a
> >>> result of
> >>> > no
> >>> > >> > integration tests yet.
> >>> > >> >
> >>> > >> >
> >>> > >> It's not clear to me if my suggestion to use the TenancyEvaluator
> >>> SPI
> >>> > >> helped ? Or, indeed, whether you have a reasonable workaround in
> >>> your
> >>> > >> current handling of the nulls?
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >>
> >>> > >> > Thanks
> >>> > >> >
> >>> > >> >
> >>> > >>
> >>> > >> [1]
> >>> > >>
> >>> > >>
> >>> >
> >>>
> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
> >>> > >>
> >>> > >>
> >>> > >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
> >>> > >> dan@haywood-associates.co.uk
> >>> > >> > >
> >>> > >> > wrote:
> >>> > >> >
> >>> > >> > > Hi Steve,
> >>> > >> > >
> >>> > >> > > Not sure I follow quite all the ins-and-outs of this, but what
> >>> could
> >>> > >> well
> >>> > >> > > be of use is the optional ApplicationTenancyPathEvaluator
> domain
> >>> > >> > > service[1]. If an implementation is registered (on the
> >>> classpath),
> >>> > >> then
> >>> > >> > > the security module will delegate to this [2] in order to
> >>> determine
> >>> > >> who
> >>> > >> > > gets to see/edit what.
> >>> > >> > >
> >>> > >> > > From what I did follow, it sounds like you need to treat
> objects
> >>> > with
> >>> > >> a
> >>> > >> > > null region in a particular way? If so, then hopefully you can
> >>> put
> >>> > >> this
> >>> > >> > > "special case" logic in an implementation of said service.
> >>> > >> > >
> >>> > >> > > HTH
> >>> > >> > > Dan
> >>> > >> > >
> >>> > >> > >
> >>> > >> > >
> >>> > >> > > [1]
> >>> > >> > >
> >>> > >> > >
> >>> > >> >
> >>> > >>
> >>> >
> >>>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> >>> > >> > > [2]
> >>> > >> > >
> >>> > >> > >
> >>> > >> >
> >>> > >>
> >>> >
> >>>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> >>> > >> > >
> >>> > >> > >
> >>> > >> > > On 25 November 2015 at 20:25, Stephen Cameron <
> >>> > >> > steve.cameron.62@gmail.com>
> >>> > >> > > wrote:
> >>> > >> > >
> >>> > >> > > > Hi,
> >>> > >> > > >
> >>> > >> > > > I have a problem with Application Tenancies not working the
> >>> way I
> >>> > >> > want, I
> >>> > >> > > > want to drive it off a field 'region', such that a person is
> >>> > >> assigned a
> >>> > >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are
> >>> also the
> >>> > >> > > regions
> >>> > >> > > > that they are working in too, so when they create a record
> >>> their
> >>> > >> region
> >>> > >> > > > gets assigned to the new record and that controls who else
> >>> can see
> >>> > >> the
> >>> > >> > > > record.
> >>> > >> > > >
> >>> > >> > > > This mostly works, but there is one small glitch. The main
> >>> > problem I
> >>> > >> > have
> >>> > >> > > > is setting it up so that region is non-null and any records
> >>> > created
> >>> > >> by
> >>> > >> > a
> >>> > >> > > > GLOBAL tenancy user are seen by all users, while those
> >>> created by
> >>> > a
> >>> > >> > > NORTH,
> >>> > >> > > > SOUTH or NORTH-WEST user are seen only by users with the
> same
> >>> > >> tenancy.
> >>> > >> > By
> >>> > >> > > > changing the region of a record it can change tenancy.
> >>> > >> > > >
> >>> > >> > > > Presently this is broken, or at least it I think it was
> >>> working
> >>> > >> > correctly
> >>> > >> > > > when I allowed a record with a region of null to be the
> GLOBAL
> >>> > >> ones. I
> >>> > >> > > need
> >>> > >> > > > to have this working for a demo tomorrow, so advice is
> >>> welcomed on
> >>> > >> how
> >>> > >> > > best
> >>> > >> > > > to set this up properly.
> >>> > >> > > >
> >>> > >> > > > My base class that controls all this here:
> >>> > >> > > >
> >>> > >> > > >
> >>> > >> > >
> >>> > >> >
> >>> > >>
> >>> >
> >>>
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> >>> > >> > > >
> >>> > >> > > > The other small glitch is that a person record created in
> the
> >>> > >> process
> >>> > >> > of
> >>> > >> > > > creating a participant doesn't get assigned a region
> >>> > automatically.
> >>> > >> I
> >>> > >> > > have
> >>> > >> > > > a work-around for that in place at present, anything that
> has
> >>> a
> >>> > null
> >>> > >> > > region
> >>> > >> > > > gets presented as having a global tenancy.
> >>> > >> > > >
> >>> > >> > > >
> >>> > >> > > > Thanks
> >>> > >> > > >
> >>> > >> > > > Steve Cameron
> >>> > >> > > >
> >>> > >> > >
> >>> > >> >
> >>> > >>
> >>> > >
> >>> > >
> >>> >
> >>>
> >>
> >>
> >
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
Yes, I still had a variable region declared in Person that was over-riding
the one in the base class I guess, so the setter was setting the super
class but the subclass value was being persisted.
On Thu, Nov 26, 2015 at 8:45 PM, Stephen Cameron <steve.cameron.62@gmail.com
> wrote:
> My silly mistake!
>
> On Thu, Nov 26, 2015 at 8:40 PM, Stephen Cameron <
> steve.cameron.62@gmail.com> wrote:
>
>> That is not the problem then,
>>
>> Its a bit bizarre actually, I generated some logging and added some
>> messages, I see that two objects Participation and Participant do have
>> their region value set but the Person object doesn't.
>>
>> All these objects extend the same base class, but the SQL insert created
>> for Person doesn't have the value whereas it does for the others.
>>
>> The code is as follows:
>>
>> @Programmatic
>> public void setUpdatedBy(String updatedBy) {
>> if (getCreatedBy() == null) {
>> setCreatedBy(updatedBy);
>> System.out.println(">>>updatedBy: " + updatedBy);
>> if (userRepository != null) {
>> System.out.println(">>>repositoryExists");
>> ApplicationUser user =
>> userRepository.findByUsername(updatedBy);
>> if (user != null && user.getTenancy() != null) {
>> String path = user.getTenancy().getPath();
>> String name = path.substring(path.lastIndexOf("/") +
>> 1);
>> if (name.isEmpty())
>> name = "GLOBAL";
>> System.out.println(">>>setting Region for name: " +
>> name);
>> setRegion(regions.regionForName(name));
>> }else{
>> System.out.println(">>>>user tenancy not found");
>> setRegion(regions.regionForName("GLOBAL")); //TODO
>> temp fix
>> }
>> }
>> else{
>> System.out.println(">>>userRepository is null");
>> setRegion(regions.regionForName("GLOBAL")); //TODO temp
>> fix
>> }
>> } else
>> setLastModifiedBy(updatedBy);
>> }
>>
>> The stdout:
>>
>>
>> 20:20:25,720 [Native qtp209845522-18 DEBUG] SELECT
>> 'au.com.scds.chats.dom.module.general.Person' AS
>> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.birthdate,a0.email,a0.emailaddress,a0.firstname,a0.homephonenumber,a0.middlename,a0.mobilephonenumber,a0.oldid,a0.preferredname,a0.surname,a0.person_id
>> FROM person a0 WHERE a0.surname = <'Ncks'>
>> >>>updatedBy: sven
>> >>>repositoryExists
>> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
>> "
>> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
>> "
>> 20:20:25,732 [Native qtp209845522-18 DEBUG] SELECT
>> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
>> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
>> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>> >>>setting Region for name: GLOBAL
>> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
>> "
>> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
>> "
>> 20:20:25,738 [Native qtp209845522-18 DEBUG] SELECT
>> 'au.com.scds.chats.dom.module.general.names.Region' AS
>> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
>> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,792 [Native qtp209845522-18 DEBUG] INSERT INTO
>> person
>> (birthdate,contacttype_name,email,emailaddress,englishskill_englishskill_id,firstname,homephonenumber,mailaddress_location_id,middlename,mobilephonenumber,oldid,preferredname,region_name,salutation_name,streetaddress_location_id,surname,createdby,createdon,lastmodifiedby,lastmodifiedon)
>> VALUES
>> (<1960-10-19>,<null>,<null>,<null>,<null>,<'Stevie'>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<'Nicks'>,<'sven'>,<2015-11-26
>> 20:20:25.74>,<null>,<null>)
>> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
>> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
>> >>>updatedBy: sven
>> >>>repositoryExists
>> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
>> "
>> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
>> "
>> 20:20:25,809 [Native qtp209845522-18 DEBUG] SELECT
>> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
>> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
>> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>> >>>setting Region for name: GLOBAL
>> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
>> "
>> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
>> "
>> 20:20:25,812 [Native qtp209845522-18 DEBUG] SELECT
>> 'au.com.scds.chats.dom.module.general.names.Region' AS
>> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
>> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,816 [Native qtp209845522-18 DEBUG] INSERT INTO
>> participant
>> (lifehistory_lifehistory_id,loneliness_loneliness_id,person_person_id,socialfactors_socialfactors_id,status,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
>> VALUES (<null>,<null>,<8>,<null>,<'ACTIVE'>,<'sven'>,<2015-11-26
>> 20:20:25.814>,<null>,<null>,<'GLOBAL'>)
>> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
>> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
>> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
>> "
>> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
>> "
>> 20:20:25,826 [Native qtp209845522-18 DEBUG] SELECT
>> 'au.com.scds.chats.dom.module.participant.Participation' AS
>> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.dropofftime,a0.oldid,a0.pickuptime,a0.roleid,a0.transportnotes,a0.participation_id
>> FROM participation a0 WHERE a0.activity_activity_id = <1>
>> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
>> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
>> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
>> "
>> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
>> "
>> 20:20:25,832 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
>> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
>> b0.activity_id WHERE a0.participation_id = <3>
>> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
>> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
>> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
>> "
>> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
>> "
>> 20:20:25,837 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
>> FROM participation a0 INNER JOIN participant b0 ON
>> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
>> = <3>
>> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
>> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
>> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
>> "
>> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
>> "
>> 20:20:25,840 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
>> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
>> b0.person_id WHERE a0.participant_id = <3>
>> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
>> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
>> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
>> "
>> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
>> "
>> 20:20:25,844 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
>> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
>> b0.activity_id WHERE a0.participation_id = <6>
>> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
>> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
>> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
>> "
>> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
>> "
>> 20:20:25,846 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
>> FROM participation a0 INNER JOIN participant b0 ON
>> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
>> = <6>
>> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
>> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
>> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
>> "
>> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
>> "
>> 20:20:25,849 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
>> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
>> b0.person_id WHERE a0.participant_id = <6>
>> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
>> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
>> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
>> "
>> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
>> "
>> 20:20:25,854 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
>> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
>> b0.activity_id WHERE a0.participation_id = <7>
>> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
>> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
>> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
>> "
>> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
>> "
>> 20:20:25,856 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
>> FROM participation a0 INNER JOIN participant b0 ON
>> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
>> = <7>
>> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
>> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
>> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
>> "
>> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
>> "
>> 20:20:25,859 [Native qtp209845522-18 DEBUG] SELECT
>> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
>> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
>> b0.person_id WHERE a0.participant_id = <7>
>> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
>> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
>> >>>updatedBy: sven
>> >>>repositoryExists
>> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
>> "
>> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
>> "
>> 20:20:25,871 [Native qtp209845522-18 DEBUG] SELECT
>> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
>> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
>> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>> >>>setting Region for name: GLOBAL
>> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
>> "
>> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
>> PreparedStatement
>> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
>> "
>> 20:20:25,881 [Native qtp209845522-18 DEBUG] SELECT
>> 'au.com.scds.chats.dom.module.general.names.Region' AS
>> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
>> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
>> PreparedStatement
>> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
>> connection
>> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
>> "
>> 20:20:25,886 [Native qtp209845522-18 DEBUG] INSERT INTO
>> participation
>> (activity_activity_id,arrivingtransporttype_name,departingtransporttype_name,dropofftime,oldid,participant_participant_id,pickuptime,roleid,transportnotes,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
>> VALUES
>> (<1>,<null>,<null>,<null>,<null>,<8>,<null>,<null>,<null>,<'sven'>,<2015-11-26
>> 20:20:25.883>,<null>,<null>,<'GLOBAL'>)
>>
>>
>> On Thu, Nov 26, 2015 at 8:11 PM, Dan Haywood <
>> dan@haywood-associates.co.uk> wrote:
>>
>>> If you just new them up:
>>>
>>> Customer cust = new Customer();
>>>
>>> then the framework doesn't know about it and any services will be null.
>>>
>>> You can then use:
>>>
>>> domainObjectContainer.injectServicesInto(cust);
>>>
>>> ~~~
>>>
>>> Alternatively, use:
>>>
>>> Customer cust = container.newTransientInstance(Customer.class);
>>>
>>> to do both steps in one.
>>>
>>> HTH
>>> Dan
>>>
>>>
>>> On 26 November 2015 at 09:09, Stephen Cameron <
>>> steve.cameron.62@gmail.com>
>>> wrote:
>>>
>>> > Hi,
>>> >
>>> > I think I've read somewhere that domain services aren't always injected
>>> > into entities by default and you sometimes have to trigger this
>>> yourself?
>>> >
>>> > Is this a correct?
>>> >
>>> > Thank
>>> >
>>> >
>>> > On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
>>> > steve.cameron.62@gmail.com> wrote:
>>> >
>>> > > I cannot try alternatives till later this evening, will let you know
>>> > > of results. If I cannot get tenancies working for tomorrow its not
>>> the
>>> > end
>>> > > of the world. I was getting "record not found" errors last night due
>>> to
>>> > > making region allowsNull="false", so a bit of a panic, given its
>>> > > mostly been working very smoothly now for a while.
>>> > >
>>> > > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
>>> > dan@haywood-associates.co.uk
>>> > > > wrote:
>>> > >
>>> > >> On 25 November 2015 at 22:26, Stephen Cameron <
>>> > steve.cameron.62@gmail.com
>>> > >> >
>>> > >> wrote:
>>> > >>
>>> > >> > Hi Dan,
>>> > >> >
>>> > >> > I did not explain it that well sorry.
>>> > >> >
>>> > >> > I want to get rid of nulls completely, the fact that I do handle
>>> them
>>> > is
>>> > >> > just a work-around for the fact that they are still being
>>> created, but
>>> > >> only
>>> > >> > for People. That is, if a new Participant is registered it looks
>>> to
>>> > see
>>> > >> if
>>> > >> > there is an existing Person with the same details then adds a new
>>> one
>>> > if
>>> > >> > not present (a single Person can be a Participant and/or a
>>> Volunteer).
>>> > >> The
>>> > >> > Participant is getting its region set in setUpdatedBy() but the
>>> Person
>>> > >> is
>>> > >> > not, I need to debug this.
>>> > >> >
>>> > >> >
>>> > >> In 1.10.0, a better approach is probably to add a subscriber to the
>>> > >> lifecycle events:
>>> > >>
>>> > >> @DomainService(nature=NatureOfService.DOMAIN)
>>> > >> public class RegionSubscriber extends AbstractSubscriber {
>>> > >>
>>> > >> @Subscribe
>>> > >> public void on(ObjectPersistingEvent ev) {
>>> > >> Object domainObject = ev.getSource();
>>> > >> }
>>> > >>
>>> > >> @Subscribe
>>> > >> public void on(ObjectUpdatingEvent ev) {
>>> > >> Object domainObject = ev.getSource();
>>> > >> }
>>> > >> }
>>> > >>
>>> > >>
>>> > >>
>>> > >>
>>> > >> > As general interest is handling such things via such a service
>>> better,
>>> > >> that
>>> > >> > is to avoid injecting services into entities if possible?
>>> > >> >
>>> > >> >
>>> > >> There's nothing wrong with injecting services into entities; it
>>> allows
>>> > >> them
>>> > >> to perform their responsibilities without leaking details of how
>>> they do
>>> > >> it
>>> > >> (their implementation) to the caller. I don't hold by this "pass
>>> in the
>>> > >> services" and "double dispatch"... I see that as a code smell.
>>> > >>
>>> > >> On the other hand, we now have a very rich set of domain events; in
>>> AOP
>>> > >> terms these are jointpoints (or is it pointcuts? see [1]), anyway
>>> they
>>> > are
>>> > >> a different way to cause "stuff to happen".
>>> > >>
>>> > >> Should one have the entity call a services, or rely on subscribers
>>> to
>>> > >> domain events? With the latter, the entity is very clean and the
>>> > >> responsibility kept completely separate. On the other hand, with
>>> events
>>> > >> the order in which the subscribers fire is non-deterministic.
>>> > >>
>>> > >>
>>> > >>
>>> > >>
>>> > >>
>>> > >>
>>> > >> > Last minute tweeks aren't the best idea, but the tests that I do
>>> have
>>> > >> are
>>> > >> > proving their value. These particular issues are probably a
>>> result of
>>> > no
>>> > >> > integration tests yet.
>>> > >> >
>>> > >> >
>>> > >> It's not clear to me if my suggestion to use the TenancyEvaluator
>>> SPI
>>> > >> helped ? Or, indeed, whether you have a reasonable workaround in
>>> your
>>> > >> current handling of the nulls?
>>> > >>
>>> > >>
>>> > >>
>>> > >>
>>> > >> > Thanks
>>> > >> >
>>> > >> >
>>> > >>
>>> > >> [1]
>>> > >>
>>> > >>
>>> >
>>> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
>>> > >>
>>> > >>
>>> > >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
>>> > >> dan@haywood-associates.co.uk
>>> > >> > >
>>> > >> > wrote:
>>> > >> >
>>> > >> > > Hi Steve,
>>> > >> > >
>>> > >> > > Not sure I follow quite all the ins-and-outs of this, but what
>>> could
>>> > >> well
>>> > >> > > be of use is the optional ApplicationTenancyPathEvaluator domain
>>> > >> > > service[1]. If an implementation is registered (on the
>>> classpath),
>>> > >> then
>>> > >> > > the security module will delegate to this [2] in order to
>>> determine
>>> > >> who
>>> > >> > > gets to see/edit what.
>>> > >> > >
>>> > >> > > From what I did follow, it sounds like you need to treat objects
>>> > with
>>> > >> a
>>> > >> > > null region in a particular way? If so, then hopefully you can
>>> put
>>> > >> this
>>> > >> > > "special case" logic in an implementation of said service.
>>> > >> > >
>>> > >> > > HTH
>>> > >> > > Dan
>>> > >> > >
>>> > >> > >
>>> > >> > >
>>> > >> > > [1]
>>> > >> > >
>>> > >> > >
>>> > >> >
>>> > >>
>>> >
>>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
>>> > >> > > [2]
>>> > >> > >
>>> > >> > >
>>> > >> >
>>> > >>
>>> >
>>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
>>> > >> > >
>>> > >> > >
>>> > >> > > On 25 November 2015 at 20:25, Stephen Cameron <
>>> > >> > steve.cameron.62@gmail.com>
>>> > >> > > wrote:
>>> > >> > >
>>> > >> > > > Hi,
>>> > >> > > >
>>> > >> > > > I have a problem with Application Tenancies not working the
>>> way I
>>> > >> > want, I
>>> > >> > > > want to drive it off a field 'region', such that a person is
>>> > >> assigned a
>>> > >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are
>>> also the
>>> > >> > > regions
>>> > >> > > > that they are working in too, so when they create a record
>>> their
>>> > >> region
>>> > >> > > > gets assigned to the new record and that controls who else
>>> can see
>>> > >> the
>>> > >> > > > record.
>>> > >> > > >
>>> > >> > > > This mostly works, but there is one small glitch. The main
>>> > problem I
>>> > >> > have
>>> > >> > > > is setting it up so that region is non-null and any records
>>> > created
>>> > >> by
>>> > >> > a
>>> > >> > > > GLOBAL tenancy user are seen by all users, while those
>>> created by
>>> > a
>>> > >> > > NORTH,
>>> > >> > > > SOUTH or NORTH-WEST user are seen only by users with the same
>>> > >> tenancy.
>>> > >> > By
>>> > >> > > > changing the region of a record it can change tenancy.
>>> > >> > > >
>>> > >> > > > Presently this is broken, or at least it I think it was
>>> working
>>> > >> > correctly
>>> > >> > > > when I allowed a record with a region of null to be the GLOBAL
>>> > >> ones. I
>>> > >> > > need
>>> > >> > > > to have this working for a demo tomorrow, so advice is
>>> welcomed on
>>> > >> how
>>> > >> > > best
>>> > >> > > > to set this up properly.
>>> > >> > > >
>>> > >> > > > My base class that controls all this here:
>>> > >> > > >
>>> > >> > > >
>>> > >> > >
>>> > >> >
>>> > >>
>>> >
>>> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
>>> > >> > > >
>>> > >> > > > The other small glitch is that a person record created in the
>>> > >> process
>>> > >> > of
>>> > >> > > > creating a participant doesn't get assigned a region
>>> > automatically.
>>> > >> I
>>> > >> > > have
>>> > >> > > > a work-around for that in place at present, anything that has
>>> a
>>> > null
>>> > >> > > region
>>> > >> > > > gets presented as having a global tenancy.
>>> > >> > > >
>>> > >> > > >
>>> > >> > > > Thanks
>>> > >> > > >
>>> > >> > > > Steve Cameron
>>> > >> > > >
>>> > >> > >
>>> > >> >
>>> > >>
>>> > >
>>> > >
>>> >
>>>
>>
>>
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
My silly mistake!
On Thu, Nov 26, 2015 at 8:40 PM, Stephen Cameron <steve.cameron.62@gmail.com
> wrote:
> That is not the problem then,
>
> Its a bit bizarre actually, I generated some logging and added some
> messages, I see that two objects Participation and Participant do have
> their region value set but the Person object doesn't.
>
> All these objects extend the same base class, but the SQL insert created
> for Person doesn't have the value whereas it does for the others.
>
> The code is as follows:
>
> @Programmatic
> public void setUpdatedBy(String updatedBy) {
> if (getCreatedBy() == null) {
> setCreatedBy(updatedBy);
> System.out.println(">>>updatedBy: " + updatedBy);
> if (userRepository != null) {
> System.out.println(">>>repositoryExists");
> ApplicationUser user =
> userRepository.findByUsername(updatedBy);
> if (user != null && user.getTenancy() != null) {
> String path = user.getTenancy().getPath();
> String name = path.substring(path.lastIndexOf("/") +
> 1);
> if (name.isEmpty())
> name = "GLOBAL";
> System.out.println(">>>setting Region for name: " +
> name);
> setRegion(regions.regionForName(name));
> }else{
> System.out.println(">>>>user tenancy not found");
> setRegion(regions.regionForName("GLOBAL")); //TODO
> temp fix
> }
> }
> else{
> System.out.println(">>>userRepository is null");
> setRegion(regions.regionForName("GLOBAL")); //TODO temp fix
> }
> } else
> setLastModifiedBy(updatedBy);
> }
>
> The stdout:
>
>
> 20:20:25,720 [Native qtp209845522-18 DEBUG] SELECT
> 'au.com.scds.chats.dom.module.general.Person' AS
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.birthdate,a0.email,a0.emailaddress,a0.firstname,a0.homephonenumber,a0.middlename,a0.mobilephonenumber,a0.oldid,a0.preferredname,a0.surname,a0.person_id
> FROM person a0 WHERE a0.surname = <'Ncks'>
> >>>updatedBy: sven
> >>>repositoryExists
> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> "
> 20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
> "
> 20:20:25,732 [Native qtp209845522-18 DEBUG] SELECT
> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >>>setting Region for name: GLOBAL
> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> "
> 20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
> "
> 20:20:25,738 [Native qtp209845522-18 DEBUG] SELECT
> 'au.com.scds.chats.dom.module.general.names.Region' AS
> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,792 [Native qtp209845522-18 DEBUG] INSERT INTO
> person
> (birthdate,contacttype_name,email,emailaddress,englishskill_englishskill_id,firstname,homephonenumber,mailaddress_location_id,middlename,mobilephonenumber,oldid,preferredname,region_name,salutation_name,streetaddress_location_id,surname,createdby,createdon,lastmodifiedby,lastmodifiedon)
> VALUES
> (<1960-10-19>,<null>,<null>,<null>,<null>,<'Stevie'>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<'Nicks'>,<'sven'>,<2015-11-26
> 20:20:25.74>,<null>,<null>)
> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> 20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
> >>>updatedBy: sven
> >>>repositoryExists
> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> "
> 20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
> "
> 20:20:25,809 [Native qtp209845522-18 DEBUG] SELECT
> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >>>setting Region for name: GLOBAL
> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> "
> 20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
> "
> 20:20:25,812 [Native qtp209845522-18 DEBUG] SELECT
> 'au.com.scds.chats.dom.module.general.names.Region' AS
> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,816 [Native qtp209845522-18 DEBUG] INSERT INTO
> participant
> (lifehistory_lifehistory_id,loneliness_loneliness_id,person_person_id,socialfactors_socialfactors_id,status,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> VALUES (<null>,<null>,<8>,<null>,<'ACTIVE'>,<'sven'>,<2015-11-26
> 20:20:25.814>,<null>,<null>,<'GLOBAL'>)
> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> 20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> "
> 20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
> "
> 20:20:25,826 [Native qtp209845522-18 DEBUG] SELECT
> 'au.com.scds.chats.dom.module.participant.Participation' AS
> NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.dropofftime,a0.oldid,a0.pickuptime,a0.roleid,a0.transportnotes,a0.participation_id
> FROM participation a0 WHERE a0.activity_activity_id = <1>
> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> 20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> "
> 20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
> "
> 20:20:25,832 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
> b0.activity_id WHERE a0.participation_id = <3>
> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> 20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> "
> 20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
> "
> 20:20:25,837 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> FROM participation a0 INNER JOIN participant b0 ON
> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
> = <3>
> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> 20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> "
> 20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
> "
> 20:20:25,840 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> b0.person_id WHERE a0.participant_id = <3>
> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> 20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> "
> 20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
> "
> 20:20:25,844 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
> b0.activity_id WHERE a0.participation_id = <6>
> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> 20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> "
> 20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
> "
> 20:20:25,846 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> FROM participation a0 INNER JOIN participant b0 ON
> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
> = <6>
> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> 20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> "
> 20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
> "
> 20:20:25,849 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> b0.person_id WHERE a0.participant_id = <6>
> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> 20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> "
> 20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
> "
> 20:20:25,854 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
> FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
> b0.activity_id WHERE a0.participation_id = <7>
> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> 20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> "
> 20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
> "
> 20:20:25,856 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
> FROM participation a0 INNER JOIN participant b0 ON
> a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
> = <7>
> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> 20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> "
> 20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
> "
> 20:20:25,859 [Native qtp209845522-18 DEBUG] SELECT
> b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
> FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
> b0.person_id WHERE a0.participant_id = <7>
> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> 20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
> >>>updatedBy: sven
> >>>repositoryExists
> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> "
> 20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
> "
> 20:20:25,871 [Native qtp209845522-18 DEBUG] SELECT
> 'org.isisaddons.module.security.dom.user.ApplicationUser' AS
> NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
> a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
> >>>setting Region for name: GLOBAL
> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> "
> 20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
> PreparedStatement
> "org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
> "
> 20:20:25,881 [Native qtp209845522-18 DEBUG] SELECT
> 'au.com.scds.chats.dom.module.general.names.Region' AS
> NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
> PreparedStatement
> "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
> connection
> "org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
> "
> 20:20:25,886 [Native qtp209845522-18 DEBUG] INSERT INTO
> participation
> (activity_activity_id,arrivingtransporttype_name,departingtransporttype_name,dropofftime,oldid,participant_participant_id,pickuptime,roleid,transportnotes,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
> VALUES
> (<1>,<null>,<null>,<null>,<null>,<8>,<null>,<null>,<null>,<'sven'>,<2015-11-26
> 20:20:25.883>,<null>,<null>,<'GLOBAL'>)
>
>
> On Thu, Nov 26, 2015 at 8:11 PM, Dan Haywood <dan@haywood-associates.co.uk
> > wrote:
>
>> If you just new them up:
>>
>> Customer cust = new Customer();
>>
>> then the framework doesn't know about it and any services will be null.
>>
>> You can then use:
>>
>> domainObjectContainer.injectServicesInto(cust);
>>
>> ~~~
>>
>> Alternatively, use:
>>
>> Customer cust = container.newTransientInstance(Customer.class);
>>
>> to do both steps in one.
>>
>> HTH
>> Dan
>>
>>
>> On 26 November 2015 at 09:09, Stephen Cameron <steve.cameron.62@gmail.com
>> >
>> wrote:
>>
>> > Hi,
>> >
>> > I think I've read somewhere that domain services aren't always injected
>> > into entities by default and you sometimes have to trigger this
>> yourself?
>> >
>> > Is this a correct?
>> >
>> > Thank
>> >
>> >
>> > On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
>> > steve.cameron.62@gmail.com> wrote:
>> >
>> > > I cannot try alternatives till later this evening, will let you know
>> > > of results. If I cannot get tenancies working for tomorrow its not the
>> > end
>> > > of the world. I was getting "record not found" errors last night due
>> to
>> > > making region allowsNull="false", so a bit of a panic, given its
>> > > mostly been working very smoothly now for a while.
>> > >
>> > > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
>> > dan@haywood-associates.co.uk
>> > > > wrote:
>> > >
>> > >> On 25 November 2015 at 22:26, Stephen Cameron <
>> > steve.cameron.62@gmail.com
>> > >> >
>> > >> wrote:
>> > >>
>> > >> > Hi Dan,
>> > >> >
>> > >> > I did not explain it that well sorry.
>> > >> >
>> > >> > I want to get rid of nulls completely, the fact that I do handle
>> them
>> > is
>> > >> > just a work-around for the fact that they are still being created,
>> but
>> > >> only
>> > >> > for People. That is, if a new Participant is registered it looks to
>> > see
>> > >> if
>> > >> > there is an existing Person with the same details then adds a new
>> one
>> > if
>> > >> > not present (a single Person can be a Participant and/or a
>> Volunteer).
>> > >> The
>> > >> > Participant is getting its region set in setUpdatedBy() but the
>> Person
>> > >> is
>> > >> > not, I need to debug this.
>> > >> >
>> > >> >
>> > >> In 1.10.0, a better approach is probably to add a subscriber to the
>> > >> lifecycle events:
>> > >>
>> > >> @DomainService(nature=NatureOfService.DOMAIN)
>> > >> public class RegionSubscriber extends AbstractSubscriber {
>> > >>
>> > >> @Subscribe
>> > >> public void on(ObjectPersistingEvent ev) {
>> > >> Object domainObject = ev.getSource();
>> > >> }
>> > >>
>> > >> @Subscribe
>> > >> public void on(ObjectUpdatingEvent ev) {
>> > >> Object domainObject = ev.getSource();
>> > >> }
>> > >> }
>> > >>
>> > >>
>> > >>
>> > >>
>> > >> > As general interest is handling such things via such a service
>> better,
>> > >> that
>> > >> > is to avoid injecting services into entities if possible?
>> > >> >
>> > >> >
>> > >> There's nothing wrong with injecting services into entities; it
>> allows
>> > >> them
>> > >> to perform their responsibilities without leaking details of how
>> they do
>> > >> it
>> > >> (their implementation) to the caller. I don't hold by this "pass in
>> the
>> > >> services" and "double dispatch"... I see that as a code smell.
>> > >>
>> > >> On the other hand, we now have a very rich set of domain events; in
>> AOP
>> > >> terms these are jointpoints (or is it pointcuts? see [1]), anyway
>> they
>> > are
>> > >> a different way to cause "stuff to happen".
>> > >>
>> > >> Should one have the entity call a services, or rely on subscribers to
>> > >> domain events? With the latter, the entity is very clean and the
>> > >> responsibility kept completely separate. On the other hand, with
>> events
>> > >> the order in which the subscribers fire is non-deterministic.
>> > >>
>> > >>
>> > >>
>> > >>
>> > >>
>> > >>
>> > >> > Last minute tweeks aren't the best idea, but the tests that I do
>> have
>> > >> are
>> > >> > proving their value. These particular issues are probably a result
>> of
>> > no
>> > >> > integration tests yet.
>> > >> >
>> > >> >
>> > >> It's not clear to me if my suggestion to use the TenancyEvaluator SPI
>> > >> helped ? Or, indeed, whether you have a reasonable workaround in
>> your
>> > >> current handling of the nulls?
>> > >>
>> > >>
>> > >>
>> > >>
>> > >> > Thanks
>> > >> >
>> > >> >
>> > >>
>> > >> [1]
>> > >>
>> > >>
>> >
>> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
>> > >>
>> > >>
>> > >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
>> > >> dan@haywood-associates.co.uk
>> > >> > >
>> > >> > wrote:
>> > >> >
>> > >> > > Hi Steve,
>> > >> > >
>> > >> > > Not sure I follow quite all the ins-and-outs of this, but what
>> could
>> > >> well
>> > >> > > be of use is the optional ApplicationTenancyPathEvaluator domain
>> > >> > > service[1]. If an implementation is registered (on the
>> classpath),
>> > >> then
>> > >> > > the security module will delegate to this [2] in order to
>> determine
>> > >> who
>> > >> > > gets to see/edit what.
>> > >> > >
>> > >> > > From what I did follow, it sounds like you need to treat objects
>> > with
>> > >> a
>> > >> > > null region in a particular way? If so, then hopefully you can
>> put
>> > >> this
>> > >> > > "special case" logic in an implementation of said service.
>> > >> > >
>> > >> > > HTH
>> > >> > > Dan
>> > >> > >
>> > >> > >
>> > >> > >
>> > >> > > [1]
>> > >> > >
>> > >> > >
>> > >> >
>> > >>
>> >
>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
>> > >> > > [2]
>> > >> > >
>> > >> > >
>> > >> >
>> > >>
>> >
>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
>> > >> > >
>> > >> > >
>> > >> > > On 25 November 2015 at 20:25, Stephen Cameron <
>> > >> > steve.cameron.62@gmail.com>
>> > >> > > wrote:
>> > >> > >
>> > >> > > > Hi,
>> > >> > > >
>> > >> > > > I have a problem with Application Tenancies not working the
>> way I
>> > >> > want, I
>> > >> > > > want to drive it off a field 'region', such that a person is
>> > >> assigned a
>> > >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also
>> the
>> > >> > > regions
>> > >> > > > that they are working in too, so when they create a record
>> their
>> > >> region
>> > >> > > > gets assigned to the new record and that controls who else can
>> see
>> > >> the
>> > >> > > > record.
>> > >> > > >
>> > >> > > > This mostly works, but there is one small glitch. The main
>> > problem I
>> > >> > have
>> > >> > > > is setting it up so that region is non-null and any records
>> > created
>> > >> by
>> > >> > a
>> > >> > > > GLOBAL tenancy user are seen by all users, while those created
>> by
>> > a
>> > >> > > NORTH,
>> > >> > > > SOUTH or NORTH-WEST user are seen only by users with the same
>> > >> tenancy.
>> > >> > By
>> > >> > > > changing the region of a record it can change tenancy.
>> > >> > > >
>> > >> > > > Presently this is broken, or at least it I think it was working
>> > >> > correctly
>> > >> > > > when I allowed a record with a region of null to be the GLOBAL
>> > >> ones. I
>> > >> > > need
>> > >> > > > to have this working for a demo tomorrow, so advice is
>> welcomed on
>> > >> how
>> > >> > > best
>> > >> > > > to set this up properly.
>> > >> > > >
>> > >> > > > My base class that controls all this here:
>> > >> > > >
>> > >> > > >
>> > >> > >
>> > >> >
>> > >>
>> >
>> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
>> > >> > > >
>> > >> > > > The other small glitch is that a person record created in the
>> > >> process
>> > >> > of
>> > >> > > > creating a participant doesn't get assigned a region
>> > automatically.
>> > >> I
>> > >> > > have
>> > >> > > > a work-around for that in place at present, anything that has a
>> > null
>> > >> > > region
>> > >> > > > gets presented as having a global tenancy.
>> > >> > > >
>> > >> > > >
>> > >> > > > Thanks
>> > >> > > >
>> > >> > > > Steve Cameron
>> > >> > > >
>> > >> > >
>> > >> >
>> > >>
>> > >
>> > >
>> >
>>
>
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
That is not the problem then,
Its a bit bizarre actually, I generated some logging and added some
messages, I see that two objects Participation and Participant do have
their region value set but the Person object doesn't.
All these objects extend the same base class, but the SQL insert created
for Person doesn't have the value whereas it does for the others.
The code is as follows:
@Programmatic
public void setUpdatedBy(String updatedBy) {
if (getCreatedBy() == null) {
setCreatedBy(updatedBy);
System.out.println(">>>updatedBy: " + updatedBy);
if (userRepository != null) {
System.out.println(">>>repositoryExists");
ApplicationUser user =
userRepository.findByUsername(updatedBy);
if (user != null && user.getTenancy() != null) {
String path = user.getTenancy().getPath();
String name = path.substring(path.lastIndexOf("/") + 1);
if (name.isEmpty())
name = "GLOBAL";
System.out.println(">>>setting Region for name: " +
name);
setRegion(regions.regionForName(name));
}else{
System.out.println(">>>>user tenancy not found");
setRegion(regions.regionForName("GLOBAL")); //TODO temp
fix
}
}
else{
System.out.println(">>>userRepository is null");
setRegion(regions.regionForName("GLOBAL")); //TODO temp fix
}
} else
setLastModifiedBy(updatedBy);
}
The stdout:
20:20:25,720 [Native qtp209845522-18 DEBUG] SELECT
'au.com.scds.chats.dom.module.general.Person' AS
NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.birthdate,a0.email,a0.emailaddress,a0.firstname,a0.homephonenumber,a0.middlename,a0.mobilephonenumber,a0.oldid,a0.preferredname,a0.surname,a0.person_id
FROM person a0 WHERE a0.surname = <'Ncks'>
>>>updatedBy: sven
>>>repositoryExists
20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
"
20:20:25,732 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76fe870e
"
20:20:25,732 [Native qtp209845522-18 DEBUG] SELECT
'org.isisaddons.module.security.dom.user.ApplicationUser' AS
NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>>>setting Region for name: GLOBAL
20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
"
20:20:25,738 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7dfe372f
"
20:20:25,738 [Native qtp209845522-18 DEBUG] SELECT
'au.com.scds.chats.dom.module.general.names.Region' AS
NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,785 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,792 [Native qtp209845522-18 DEBUG] INSERT INTO
person
(birthdate,contacttype_name,email,emailaddress,englishskill_englishskill_id,firstname,homephonenumber,mailaddress_location_id,middlename,mobilephonenumber,oldid,preferredname,region_name,salutation_name,streetaddress_location_id,surname,createdby,createdon,lastmodifiedby,lastmodifiedon)
VALUES
(<1960-10-19>,<null>,<null>,<null>,<null>,<'Stevie'>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<'Nicks'>,<'sven'>,<2015-11-26
20:20:25.74>,<null>,<null>)
20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
20:20:25,795 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@74efbe8f"
>>>updatedBy: sven
>>>repositoryExists
20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
"
20:20:25,808 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6822e803
"
20:20:25,809 [Native qtp209845522-18 DEBUG] SELECT
'org.isisaddons.module.security.dom.user.ApplicationUser' AS
NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>>>setting Region for name: GLOBAL
20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
"
20:20:25,812 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6949a458
"
20:20:25,812 [Native qtp209845522-18 DEBUG] SELECT
'au.com.scds.chats.dom.module.general.names.Region' AS
NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,815 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,816 [Native qtp209845522-18 DEBUG] INSERT INTO
participant
(lifehistory_lifehistory_id,loneliness_loneliness_id,person_person_id,socialfactors_socialfactors_id,status,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
VALUES (<null>,<null>,<8>,<null>,<'ACTIVE'>,<'sven'>,<2015-11-26
20:20:25.814>,<null>,<null>,<'GLOBAL'>)
20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
20:20:25,817 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@7fb858f5"
20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
"
20:20:25,825 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@6eb9aa9a
"
20:20:25,826 [Native qtp209845522-18 DEBUG] SELECT
'au.com.scds.chats.dom.module.participant.Participation' AS
NUCLEUS_TYPE,a0.createdby,a0.createdon,a0.lastmodifiedby,a0.lastmodifiedon,a0.dropofftime,a0.oldid,a0.pickuptime,a0.roleid,a0.transportnotes,a0.participation_id
FROM participation a0 WHERE a0.activity_activity_id = <1>
20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
20:20:25,831 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@34a88772"
20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
"
20:20:25,832 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@5578fea9
"
20:20:25,832 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
b0.activity_id WHERE a0.participation_id = <3>
20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
20:20:25,835 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@456274da"
20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
"
20:20:25,836 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@57f25c32
"
20:20:25,837 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
FROM participation a0 INNER JOIN participant b0 ON
a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
= <3>
20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
20:20:25,839 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@1554ed8e"
20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
"
20:20:25,840 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@76978806
"
20:20:25,840 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
b0.person_id WHERE a0.participant_id = <3>
20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
20:20:25,843 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@66f47ad4"
20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
"
20:20:25,844 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@64779748
"
20:20:25,844 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
b0.activity_id WHERE a0.participation_id = <6>
20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
20:20:25,845 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@e5ed16d"
20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
"
20:20:25,846 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@328b4a67
"
20:20:25,846 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
FROM participation a0 INNER JOIN participant b0 ON
a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
= <6>
20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
20:20:25,848 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@507670dd"
20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
"
20:20:25,849 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@fec3f19
"
20:20:25,849 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
b0.person_id WHERE a0.participant_id = <6>
20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
20:20:25,852 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@46f3839a"
20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
"
20:20:25,853 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7546f02f
"
20:20:25,854 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.approximateenddatetime,b0.copiedfromactivityid,b0.costforparticipant,b0.description,b0.isrestricted,b0.`name`,b0.oldid,b0.scheduleid,b0.startdatetime,b0.activity_id,b0.classifier
FROM participation a0 INNER JOIN activity b0 ON a0.activity_activity_id =
b0.activity_id WHERE a0.participation_id = <7>
20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
20:20:25,855 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@a3e5286"
20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
"
20:20:25,856 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@2b9465d6
"
20:20:25,856 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.status,b0.participant_id
FROM participation a0 INNER JOIN participant b0 ON
a0.participant_participant_id = b0.participant_id WHERE a0.participation_id
= <7>
20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
20:20:25,858 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@3c2b0e6c"
20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
"
20:20:25,859 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@676002a
"
20:20:25,859 [Native qtp209845522-18 DEBUG] SELECT
b0.createdby,b0.createdon,b0.lastmodifiedby,b0.lastmodifiedon,b0.birthdate,b0.email,b0.emailaddress,b0.firstname,b0.homephonenumber,b0.middlename,b0.mobilephonenumber,b0.oldid,b0.preferredname,b0.surname,b0.person_id
FROM participant a0 INNER JOIN person b0 ON a0.person_person_id =
b0.person_id WHERE a0.participant_id = <7>
20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
20:20:25,863 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@41ab2f40"
>>>updatedBy: sven
>>>repositoryExists
20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
"
20:20:25,871 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@65dc18d2
"
20:20:25,871 [Native qtp209845522-18 DEBUG] SELECT
'org.isisaddons.module.security.dom.user.ApplicationUser' AS
NUCLEUS_TYPE,a0.accounttype,a0.emailaddress,a0.encryptedpassword,a0.familyname,a0.faxnumber,a0.givenname,a0.knownas,a0.phonenumber,a0.status,a0.username,
a0.id,a0.version FROM applicationuser a0 WHERE a0.username = <'sven'>
>>>setting Region for name: GLOBAL
20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
"
20:20:25,875 [Datastore qtp209845522-18 DEBUG] Closing
PreparedStatement
"org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement@7a2183e6
"
20:20:25,881 [Native qtp209845522-18 DEBUG] SELECT
'au.com.scds.chats.dom.module.general.names.Region' AS
NUCLEUS_TYPE,a0.`name` FROM region a0 WHERE a0.`name` = <'GLOBAL'>
20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,885 [Datastore qtp209845522-18 DEBUG] Using
PreparedStatement
"org.datanucleus.store.rdbms.ParamLoggingPreparedStatement@63c44673" for
connection
"org.datanucleus.store.rdbms.datasource.dbcp.PoolingDataSource$PoolGuardConnectionWrapper@15e2c48d
"
20:20:25,886 [Native qtp209845522-18 DEBUG] INSERT INTO
participation
(activity_activity_id,arrivingtransporttype_name,departingtransporttype_name,dropofftime,oldid,participant_participant_id,pickuptime,roleid,transportnotes,createdby,createdon,lastmodifiedby,lastmodifiedon,region_name)
VALUES
(<1>,<null>,<null>,<null>,<null>,<8>,<null>,<null>,<null>,<'sven'>,<2015-11-26
20:20:25.883>,<null>,<null>,<'GLOBAL'>)
On Thu, Nov 26, 2015 at 8:11 PM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:
> If you just new them up:
>
> Customer cust = new Customer();
>
> then the framework doesn't know about it and any services will be null.
>
> You can then use:
>
> domainObjectContainer.injectServicesInto(cust);
>
> ~~~
>
> Alternatively, use:
>
> Customer cust = container.newTransientInstance(Customer.class);
>
> to do both steps in one.
>
> HTH
> Dan
>
>
> On 26 November 2015 at 09:09, Stephen Cameron <st...@gmail.com>
> wrote:
>
> > Hi,
> >
> > I think I've read somewhere that domain services aren't always injected
> > into entities by default and you sometimes have to trigger this yourself?
> >
> > Is this a correct?
> >
> > Thank
> >
> >
> > On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
> > steve.cameron.62@gmail.com> wrote:
> >
> > > I cannot try alternatives till later this evening, will let you know
> > > of results. If I cannot get tenancies working for tomorrow its not the
> > end
> > > of the world. I was getting "record not found" errors last night due to
> > > making region allowsNull="false", so a bit of a panic, given its
> > > mostly been working very smoothly now for a while.
> > >
> > > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
> > dan@haywood-associates.co.uk
> > > > wrote:
> > >
> > >> On 25 November 2015 at 22:26, Stephen Cameron <
> > steve.cameron.62@gmail.com
> > >> >
> > >> wrote:
> > >>
> > >> > Hi Dan,
> > >> >
> > >> > I did not explain it that well sorry.
> > >> >
> > >> > I want to get rid of nulls completely, the fact that I do handle
> them
> > is
> > >> > just a work-around for the fact that they are still being created,
> but
> > >> only
> > >> > for People. That is, if a new Participant is registered it looks to
> > see
> > >> if
> > >> > there is an existing Person with the same details then adds a new
> one
> > if
> > >> > not present (a single Person can be a Participant and/or a
> Volunteer).
> > >> The
> > >> > Participant is getting its region set in setUpdatedBy() but the
> Person
> > >> is
> > >> > not, I need to debug this.
> > >> >
> > >> >
> > >> In 1.10.0, a better approach is probably to add a subscriber to the
> > >> lifecycle events:
> > >>
> > >> @DomainService(nature=NatureOfService.DOMAIN)
> > >> public class RegionSubscriber extends AbstractSubscriber {
> > >>
> > >> @Subscribe
> > >> public void on(ObjectPersistingEvent ev) {
> > >> Object domainObject = ev.getSource();
> > >> }
> > >>
> > >> @Subscribe
> > >> public void on(ObjectUpdatingEvent ev) {
> > >> Object domainObject = ev.getSource();
> > >> }
> > >> }
> > >>
> > >>
> > >>
> > >>
> > >> > As general interest is handling such things via such a service
> better,
> > >> that
> > >> > is to avoid injecting services into entities if possible?
> > >> >
> > >> >
> > >> There's nothing wrong with injecting services into entities; it allows
> > >> them
> > >> to perform their responsibilities without leaking details of how they
> do
> > >> it
> > >> (their implementation) to the caller. I don't hold by this "pass in
> the
> > >> services" and "double dispatch"... I see that as a code smell.
> > >>
> > >> On the other hand, we now have a very rich set of domain events; in
> AOP
> > >> terms these are jointpoints (or is it pointcuts? see [1]), anyway they
> > are
> > >> a different way to cause "stuff to happen".
> > >>
> > >> Should one have the entity call a services, or rely on subscribers to
> > >> domain events? With the latter, the entity is very clean and the
> > >> responsibility kept completely separate. On the other hand, with
> events
> > >> the order in which the subscribers fire is non-deterministic.
> > >>
> > >>
> > >>
> > >>
> > >>
> > >>
> > >> > Last minute tweeks aren't the best idea, but the tests that I do
> have
> > >> are
> > >> > proving their value. These particular issues are probably a result
> of
> > no
> > >> > integration tests yet.
> > >> >
> > >> >
> > >> It's not clear to me if my suggestion to use the TenancyEvaluator SPI
> > >> helped ? Or, indeed, whether you have a reasonable workaround in your
> > >> current handling of the nulls?
> > >>
> > >>
> > >>
> > >>
> > >> > Thanks
> > >> >
> > >> >
> > >>
> > >> [1]
> > >>
> > >>
> >
> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
> > >>
> > >>
> > >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
> > >> dan@haywood-associates.co.uk
> > >> > >
> > >> > wrote:
> > >> >
> > >> > > Hi Steve,
> > >> > >
> > >> > > Not sure I follow quite all the ins-and-outs of this, but what
> could
> > >> well
> > >> > > be of use is the optional ApplicationTenancyPathEvaluator domain
> > >> > > service[1]. If an implementation is registered (on the
> classpath),
> > >> then
> > >> > > the security module will delegate to this [2] in order to
> determine
> > >> who
> > >> > > gets to see/edit what.
> > >> > >
> > >> > > From what I did follow, it sounds like you need to treat objects
> > with
> > >> a
> > >> > > null region in a particular way? If so, then hopefully you can put
> > >> this
> > >> > > "special case" logic in an implementation of said service.
> > >> > >
> > >> > > HTH
> > >> > > Dan
> > >> > >
> > >> > >
> > >> > >
> > >> > > [1]
> > >> > >
> > >> > >
> > >> >
> > >>
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> > >> > > [2]
> > >> > >
> > >> > >
> > >> >
> > >>
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> > >> > >
> > >> > >
> > >> > > On 25 November 2015 at 20:25, Stephen Cameron <
> > >> > steve.cameron.62@gmail.com>
> > >> > > wrote:
> > >> > >
> > >> > > > Hi,
> > >> > > >
> > >> > > > I have a problem with Application Tenancies not working the way
> I
> > >> > want, I
> > >> > > > want to drive it off a field 'region', such that a person is
> > >> assigned a
> > >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also
> the
> > >> > > regions
> > >> > > > that they are working in too, so when they create a record their
> > >> region
> > >> > > > gets assigned to the new record and that controls who else can
> see
> > >> the
> > >> > > > record.
> > >> > > >
> > >> > > > This mostly works, but there is one small glitch. The main
> > problem I
> > >> > have
> > >> > > > is setting it up so that region is non-null and any records
> > created
> > >> by
> > >> > a
> > >> > > > GLOBAL tenancy user are seen by all users, while those created
> by
> > a
> > >> > > NORTH,
> > >> > > > SOUTH or NORTH-WEST user are seen only by users with the same
> > >> tenancy.
> > >> > By
> > >> > > > changing the region of a record it can change tenancy.
> > >> > > >
> > >> > > > Presently this is broken, or at least it I think it was working
> > >> > correctly
> > >> > > > when I allowed a record with a region of null to be the GLOBAL
> > >> ones. I
> > >> > > need
> > >> > > > to have this working for a demo tomorrow, so advice is welcomed
> on
> > >> how
> > >> > > best
> > >> > > > to set this up properly.
> > >> > > >
> > >> > > > My base class that controls all this here:
> > >> > > >
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> > >> > > >
> > >> > > > The other small glitch is that a person record created in the
> > >> process
> > >> > of
> > >> > > > creating a participant doesn't get assigned a region
> > automatically.
> > >> I
> > >> > > have
> > >> > > > a work-around for that in place at present, anything that has a
> > null
> > >> > > region
> > >> > > > gets presented as having a global tenancy.
> > >> > > >
> > >> > > >
> > >> > > > Thanks
> > >> > > >
> > >> > > > Steve Cameron
> > >> > > >
> > >> > >
> > >> >
> > >>
> > >
> > >
> >
>
Re: Application Tenancy
Posted by Dan Haywood <da...@haywood-associates.co.uk>.
If you just new them up:
Customer cust = new Customer();
then the framework doesn't know about it and any services will be null.
You can then use:
domainObjectContainer.injectServicesInto(cust);
~~~
Alternatively, use:
Customer cust = container.newTransientInstance(Customer.class);
to do both steps in one.
HTH
Dan
On 26 November 2015 at 09:09, Stephen Cameron <st...@gmail.com>
wrote:
> Hi,
>
> I think I've read somewhere that domain services aren't always injected
> into entities by default and you sometimes have to trigger this yourself?
>
> Is this a correct?
>
> Thank
>
>
> On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
> steve.cameron.62@gmail.com> wrote:
>
> > I cannot try alternatives till later this evening, will let you know
> > of results. If I cannot get tenancies working for tomorrow its not the
> end
> > of the world. I was getting "record not found" errors last night due to
> > making region allowsNull="false", so a bit of a panic, given its
> > mostly been working very smoothly now for a while.
> >
> > On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <
> dan@haywood-associates.co.uk
> > > wrote:
> >
> >> On 25 November 2015 at 22:26, Stephen Cameron <
> steve.cameron.62@gmail.com
> >> >
> >> wrote:
> >>
> >> > Hi Dan,
> >> >
> >> > I did not explain it that well sorry.
> >> >
> >> > I want to get rid of nulls completely, the fact that I do handle them
> is
> >> > just a work-around for the fact that they are still being created, but
> >> only
> >> > for People. That is, if a new Participant is registered it looks to
> see
> >> if
> >> > there is an existing Person with the same details then adds a new one
> if
> >> > not present (a single Person can be a Participant and/or a Volunteer).
> >> The
> >> > Participant is getting its region set in setUpdatedBy() but the Person
> >> is
> >> > not, I need to debug this.
> >> >
> >> >
> >> In 1.10.0, a better approach is probably to add a subscriber to the
> >> lifecycle events:
> >>
> >> @DomainService(nature=NatureOfService.DOMAIN)
> >> public class RegionSubscriber extends AbstractSubscriber {
> >>
> >> @Subscribe
> >> public void on(ObjectPersistingEvent ev) {
> >> Object domainObject = ev.getSource();
> >> }
> >>
> >> @Subscribe
> >> public void on(ObjectUpdatingEvent ev) {
> >> Object domainObject = ev.getSource();
> >> }
> >> }
> >>
> >>
> >>
> >>
> >> > As general interest is handling such things via such a service better,
> >> that
> >> > is to avoid injecting services into entities if possible?
> >> >
> >> >
> >> There's nothing wrong with injecting services into entities; it allows
> >> them
> >> to perform their responsibilities without leaking details of how they do
> >> it
> >> (their implementation) to the caller. I don't hold by this "pass in the
> >> services" and "double dispatch"... I see that as a code smell.
> >>
> >> On the other hand, we now have a very rich set of domain events; in AOP
> >> terms these are jointpoints (or is it pointcuts? see [1]), anyway they
> are
> >> a different way to cause "stuff to happen".
> >>
> >> Should one have the entity call a services, or rely on subscribers to
> >> domain events? With the latter, the entity is very clean and the
> >> responsibility kept completely separate. On the other hand, with events
> >> the order in which the subscribers fire is non-deterministic.
> >>
> >>
> >>
> >>
> >>
> >>
> >> > Last minute tweeks aren't the best idea, but the tests that I do have
> >> are
> >> > proving their value. These particular issues are probably a result of
> no
> >> > integration tests yet.
> >> >
> >> >
> >> It's not clear to me if my suggestion to use the TenancyEvaluator SPI
> >> helped ? Or, indeed, whether you have a reasonable workaround in your
> >> current handling of the nulls?
> >>
> >>
> >>
> >>
> >> > Thanks
> >> >
> >> >
> >>
> >> [1]
> >>
> >>
> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
> >>
> >>
> >> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
> >> dan@haywood-associates.co.uk
> >> > >
> >> > wrote:
> >> >
> >> > > Hi Steve,
> >> > >
> >> > > Not sure I follow quite all the ins-and-outs of this, but what could
> >> well
> >> > > be of use is the optional ApplicationTenancyPathEvaluator domain
> >> > > service[1]. If an implementation is registered (on the classpath),
> >> then
> >> > > the security module will delegate to this [2] in order to determine
> >> who
> >> > > gets to see/edit what.
> >> > >
> >> > > From what I did follow, it sounds like you need to treat objects
> with
> >> a
> >> > > null region in a particular way? If so, then hopefully you can put
> >> this
> >> > > "special case" logic in an implementation of said service.
> >> > >
> >> > > HTH
> >> > > Dan
> >> > >
> >> > >
> >> > >
> >> > > [1]
> >> > >
> >> > >
> >> >
> >>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> >> > > [2]
> >> > >
> >> > >
> >> >
> >>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> >> > >
> >> > >
> >> > > On 25 November 2015 at 20:25, Stephen Cameron <
> >> > steve.cameron.62@gmail.com>
> >> > > wrote:
> >> > >
> >> > > > Hi,
> >> > > >
> >> > > > I have a problem with Application Tenancies not working the way I
> >> > want, I
> >> > > > want to drive it off a field 'region', such that a person is
> >> assigned a
> >> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the
> >> > > regions
> >> > > > that they are working in too, so when they create a record their
> >> region
> >> > > > gets assigned to the new record and that controls who else can see
> >> the
> >> > > > record.
> >> > > >
> >> > > > This mostly works, but there is one small glitch. The main
> problem I
> >> > have
> >> > > > is setting it up so that region is non-null and any records
> created
> >> by
> >> > a
> >> > > > GLOBAL tenancy user are seen by all users, while those created by
> a
> >> > > NORTH,
> >> > > > SOUTH or NORTH-WEST user are seen only by users with the same
> >> tenancy.
> >> > By
> >> > > > changing the region of a record it can change tenancy.
> >> > > >
> >> > > > Presently this is broken, or at least it I think it was working
> >> > correctly
> >> > > > when I allowed a record with a region of null to be the GLOBAL
> >> ones. I
> >> > > need
> >> > > > to have this working for a demo tomorrow, so advice is welcomed on
> >> how
> >> > > best
> >> > > > to set this up properly.
> >> > > >
> >> > > > My base class that controls all this here:
> >> > > >
> >> > > >
> >> > >
> >> >
> >>
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> >> > > >
> >> > > > The other small glitch is that a person record created in the
> >> process
> >> > of
> >> > > > creating a participant doesn't get assigned a region
> automatically.
> >> I
> >> > > have
> >> > > > a work-around for that in place at present, anything that has a
> null
> >> > > region
> >> > > > gets presented as having a global tenancy.
> >> > > >
> >> > > >
> >> > > > Thanks
> >> > > >
> >> > > > Steve Cameron
> >> > > >
> >> > >
> >> >
> >>
> >
> >
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
Hi,
I think I've read somewhere that domain services aren't always injected
into entities by default and you sometimes have to trigger this yourself?
Is this a correct?
Thank
On Thu, Nov 26, 2015 at 10:00 AM, Stephen Cameron <
steve.cameron.62@gmail.com> wrote:
> I cannot try alternatives till later this evening, will let you know
> of results. If I cannot get tenancies working for tomorrow its not the end
> of the world. I was getting "record not found" errors last night due to
> making region allowsNull="false", so a bit of a panic, given its
> mostly been working very smoothly now for a while.
>
> On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <dan@haywood-associates.co.uk
> > wrote:
>
>> On 25 November 2015 at 22:26, Stephen Cameron <steve.cameron.62@gmail.com
>> >
>> wrote:
>>
>> > Hi Dan,
>> >
>> > I did not explain it that well sorry.
>> >
>> > I want to get rid of nulls completely, the fact that I do handle them is
>> > just a work-around for the fact that they are still being created, but
>> only
>> > for People. That is, if a new Participant is registered it looks to see
>> if
>> > there is an existing Person with the same details then adds a new one if
>> > not present (a single Person can be a Participant and/or a Volunteer).
>> The
>> > Participant is getting its region set in setUpdatedBy() but the Person
>> is
>> > not, I need to debug this.
>> >
>> >
>> In 1.10.0, a better approach is probably to add a subscriber to the
>> lifecycle events:
>>
>> @DomainService(nature=NatureOfService.DOMAIN)
>> public class RegionSubscriber extends AbstractSubscriber {
>>
>> @Subscribe
>> public void on(ObjectPersistingEvent ev) {
>> Object domainObject = ev.getSource();
>> }
>>
>> @Subscribe
>> public void on(ObjectUpdatingEvent ev) {
>> Object domainObject = ev.getSource();
>> }
>> }
>>
>>
>>
>>
>> > As general interest is handling such things via such a service better,
>> that
>> > is to avoid injecting services into entities if possible?
>> >
>> >
>> There's nothing wrong with injecting services into entities; it allows
>> them
>> to perform their responsibilities without leaking details of how they do
>> it
>> (their implementation) to the caller. I don't hold by this "pass in the
>> services" and "double dispatch"... I see that as a code smell.
>>
>> On the other hand, we now have a very rich set of domain events; in AOP
>> terms these are jointpoints (or is it pointcuts? see [1]), anyway they are
>> a different way to cause "stuff to happen".
>>
>> Should one have the entity call a services, or rely on subscribers to
>> domain events? With the latter, the entity is very clean and the
>> responsibility kept completely separate. On the other hand, with events
>> the order in which the subscribers fire is non-deterministic.
>>
>>
>>
>>
>>
>>
>> > Last minute tweeks aren't the best idea, but the tests that I do have
>> are
>> > proving their value. These particular issues are probably a result of no
>> > integration tests yet.
>> >
>> >
>> It's not clear to me if my suggestion to use the TenancyEvaluator SPI
>> helped ? Or, indeed, whether you have a reasonable workaround in your
>> current handling of the nulls?
>>
>>
>>
>>
>> > Thanks
>> >
>> >
>>
>> [1]
>>
>> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
>>
>>
>> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
>> dan@haywood-associates.co.uk
>> > >
>> > wrote:
>> >
>> > > Hi Steve,
>> > >
>> > > Not sure I follow quite all the ins-and-outs of this, but what could
>> well
>> > > be of use is the optional ApplicationTenancyPathEvaluator domain
>> > > service[1]. If an implementation is registered (on the classpath),
>> then
>> > > the security module will delegate to this [2] in order to determine
>> who
>> > > gets to see/edit what.
>> > >
>> > > From what I did follow, it sounds like you need to treat objects with
>> a
>> > > null region in a particular way? If so, then hopefully you can put
>> this
>> > > "special case" logic in an implementation of said service.
>> > >
>> > > HTH
>> > > Dan
>> > >
>> > >
>> > >
>> > > [1]
>> > >
>> > >
>> >
>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
>> > > [2]
>> > >
>> > >
>> >
>> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
>> > >
>> > >
>> > > On 25 November 2015 at 20:25, Stephen Cameron <
>> > steve.cameron.62@gmail.com>
>> > > wrote:
>> > >
>> > > > Hi,
>> > > >
>> > > > I have a problem with Application Tenancies not working the way I
>> > want, I
>> > > > want to drive it off a field 'region', such that a person is
>> assigned a
>> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the
>> > > regions
>> > > > that they are working in too, so when they create a record their
>> region
>> > > > gets assigned to the new record and that controls who else can see
>> the
>> > > > record.
>> > > >
>> > > > This mostly works, but there is one small glitch. The main problem I
>> > have
>> > > > is setting it up so that region is non-null and any records created
>> by
>> > a
>> > > > GLOBAL tenancy user are seen by all users, while those created by a
>> > > NORTH,
>> > > > SOUTH or NORTH-WEST user are seen only by users with the same
>> tenancy.
>> > By
>> > > > changing the region of a record it can change tenancy.
>> > > >
>> > > > Presently this is broken, or at least it I think it was working
>> > correctly
>> > > > when I allowed a record with a region of null to be the GLOBAL
>> ones. I
>> > > need
>> > > > to have this working for a demo tomorrow, so advice is welcomed on
>> how
>> > > best
>> > > > to set this up properly.
>> > > >
>> > > > My base class that controls all this here:
>> > > >
>> > > >
>> > >
>> >
>> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
>> > > >
>> > > > The other small glitch is that a person record created in the
>> process
>> > of
>> > > > creating a participant doesn't get assigned a region automatically.
>> I
>> > > have
>> > > > a work-around for that in place at present, anything that has a null
>> > > region
>> > > > gets presented as having a global tenancy.
>> > > >
>> > > >
>> > > > Thanks
>> > > >
>> > > > Steve Cameron
>> > > >
>> > >
>> >
>>
>
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
I cannot try alternatives till later this evening, will let you know
of results. If I cannot get tenancies working for tomorrow its not the end
of the world. I was getting "record not found" errors last night due to
making region allowsNull="false", so a bit of a panic, given its
mostly been working very smoothly now for a while.
On Thu, Nov 26, 2015 at 9:40 AM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:
> On 25 November 2015 at 22:26, Stephen Cameron <st...@gmail.com>
> wrote:
>
> > Hi Dan,
> >
> > I did not explain it that well sorry.
> >
> > I want to get rid of nulls completely, the fact that I do handle them is
> > just a work-around for the fact that they are still being created, but
> only
> > for People. That is, if a new Participant is registered it looks to see
> if
> > there is an existing Person with the same details then adds a new one if
> > not present (a single Person can be a Participant and/or a Volunteer).
> The
> > Participant is getting its region set in setUpdatedBy() but the Person is
> > not, I need to debug this.
> >
> >
> In 1.10.0, a better approach is probably to add a subscriber to the
> lifecycle events:
>
> @DomainService(nature=NatureOfService.DOMAIN)
> public class RegionSubscriber extends AbstractSubscriber {
>
> @Subscribe
> public void on(ObjectPersistingEvent ev) {
> Object domainObject = ev.getSource();
> }
>
> @Subscribe
> public void on(ObjectUpdatingEvent ev) {
> Object domainObject = ev.getSource();
> }
> }
>
>
>
>
> > As general interest is handling such things via such a service better,
> that
> > is to avoid injecting services into entities if possible?
> >
> >
> There's nothing wrong with injecting services into entities; it allows them
> to perform their responsibilities without leaking details of how they do it
> (their implementation) to the caller. I don't hold by this "pass in the
> services" and "double dispatch"... I see that as a code smell.
>
> On the other hand, we now have a very rich set of domain events; in AOP
> terms these are jointpoints (or is it pointcuts? see [1]), anyway they are
> a different way to cause "stuff to happen".
>
> Should one have the entity call a services, or rely on subscribers to
> domain events? With the latter, the entity is very clean and the
> responsibility kept completely separate. On the other hand, with events
> the order in which the subscribers fire is non-deterministic.
>
>
>
>
>
>
> > Last minute tweeks aren't the best idea, but the tests that I do have are
> > proving their value. These particular issues are probably a result of no
> > integration tests yet.
> >
> >
> It's not clear to me if my suggestion to use the TenancyEvaluator SPI
> helped ? Or, indeed, whether you have a reasonable workaround in your
> current handling of the nulls?
>
>
>
>
> > Thanks
> >
> >
>
> [1]
>
> http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
>
>
> > On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <
> dan@haywood-associates.co.uk
> > >
> > wrote:
> >
> > > Hi Steve,
> > >
> > > Not sure I follow quite all the ins-and-outs of this, but what could
> well
> > > be of use is the optional ApplicationTenancyPathEvaluator domain
> > > service[1]. If an implementation is registered (on the classpath),
> then
> > > the security module will delegate to this [2] in order to determine who
> > > gets to see/edit what.
> > >
> > > From what I did follow, it sounds like you need to treat objects with a
> > > null region in a particular way? If so, then hopefully you can put this
> > > "special case" logic in an implementation of said service.
> > >
> > > HTH
> > > Dan
> > >
> > >
> > >
> > > [1]
> > >
> > >
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> > > [2]
> > >
> > >
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> > >
> > >
> > > On 25 November 2015 at 20:25, Stephen Cameron <
> > steve.cameron.62@gmail.com>
> > > wrote:
> > >
> > > > Hi,
> > > >
> > > > I have a problem with Application Tenancies not working the way I
> > want, I
> > > > want to drive it off a field 'region', such that a person is
> assigned a
> > > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the
> > > regions
> > > > that they are working in too, so when they create a record their
> region
> > > > gets assigned to the new record and that controls who else can see
> the
> > > > record.
> > > >
> > > > This mostly works, but there is one small glitch. The main problem I
> > have
> > > > is setting it up so that region is non-null and any records created
> by
> > a
> > > > GLOBAL tenancy user are seen by all users, while those created by a
> > > NORTH,
> > > > SOUTH or NORTH-WEST user are seen only by users with the same
> tenancy.
> > By
> > > > changing the region of a record it can change tenancy.
> > > >
> > > > Presently this is broken, or at least it I think it was working
> > correctly
> > > > when I allowed a record with a region of null to be the GLOBAL ones.
> I
> > > need
> > > > to have this working for a demo tomorrow, so advice is welcomed on
> how
> > > best
> > > > to set this up properly.
> > > >
> > > > My base class that controls all this here:
> > > >
> > > >
> > >
> >
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> > > >
> > > > The other small glitch is that a person record created in the process
> > of
> > > > creating a participant doesn't get assigned a region automatically. I
> > > have
> > > > a work-around for that in place at present, anything that has a null
> > > region
> > > > gets presented as having a global tenancy.
> > > >
> > > >
> > > > Thanks
> > > >
> > > > Steve Cameron
> > > >
> > >
> >
>
Re: Application Tenancy
Posted by Dan Haywood <da...@haywood-associates.co.uk>.
On 25 November 2015 at 22:26, Stephen Cameron <st...@gmail.com>
wrote:
> Hi Dan,
>
> I did not explain it that well sorry.
>
> I want to get rid of nulls completely, the fact that I do handle them is
> just a work-around for the fact that they are still being created, but only
> for People. That is, if a new Participant is registered it looks to see if
> there is an existing Person with the same details then adds a new one if
> not present (a single Person can be a Participant and/or a Volunteer). The
> Participant is getting its region set in setUpdatedBy() but the Person is
> not, I need to debug this.
>
>
In 1.10.0, a better approach is probably to add a subscriber to the
lifecycle events:
@DomainService(nature=NatureOfService.DOMAIN)
public class RegionSubscriber extends AbstractSubscriber {
@Subscribe
public void on(ObjectPersistingEvent ev) {
Object domainObject = ev.getSource();
}
@Subscribe
public void on(ObjectUpdatingEvent ev) {
Object domainObject = ev.getSource();
}
}
> As general interest is handling such things via such a service better, that
> is to avoid injecting services into entities if possible?
>
>
There's nothing wrong with injecting services into entities; it allows them
to perform their responsibilities without leaking details of how they do it
(their implementation) to the caller. I don't hold by this "pass in the
services" and "double dispatch"... I see that as a code smell.
On the other hand, we now have a very rich set of domain events; in AOP
terms these are jointpoints (or is it pointcuts? see [1]), anyway they are
a different way to cause "stuff to happen".
Should one have the entity call a services, or rely on subscribers to
domain events? With the latter, the entity is very clean and the
responsibility kept completely separate. On the other hand, with events
the order in which the subscribers fire is non-deterministic.
> Last minute tweeks aren't the best idea, but the tests that I do have are
> proving their value. These particular issues are probably a result of no
> integration tests yet.
>
>
It's not clear to me if my suggestion to use the TenancyEvaluator SPI
helped ? Or, indeed, whether you have a reasonable workaround in your
current handling of the nulls?
> Thanks
>
>
[1]
http://stackoverflow.com/questions/15447397/spring-aop-whats-the-difference-between-joinpoint-and-pointcut
> On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <dan@haywood-associates.co.uk
> >
> wrote:
>
> > Hi Steve,
> >
> > Not sure I follow quite all the ins-and-outs of this, but what could well
> > be of use is the optional ApplicationTenancyPathEvaluator domain
> > service[1]. If an implementation is registered (on the classpath), then
> > the security module will delegate to this [2] in order to determine who
> > gets to see/edit what.
> >
> > From what I did follow, it sounds like you need to treat objects with a
> > null region in a particular way? If so, then hopefully you can put this
> > "special case" logic in an implementation of said service.
> >
> > HTH
> > Dan
> >
> >
> >
> > [1]
> >
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> > [2]
> >
> >
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
> >
> >
> > On 25 November 2015 at 20:25, Stephen Cameron <
> steve.cameron.62@gmail.com>
> > wrote:
> >
> > > Hi,
> > >
> > > I have a problem with Application Tenancies not working the way I
> want, I
> > > want to drive it off a field 'region', such that a person is assigned a
> > > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the
> > regions
> > > that they are working in too, so when they create a record their region
> > > gets assigned to the new record and that controls who else can see the
> > > record.
> > >
> > > This mostly works, but there is one small glitch. The main problem I
> have
> > > is setting it up so that region is non-null and any records created by
> a
> > > GLOBAL tenancy user are seen by all users, while those created by a
> > NORTH,
> > > SOUTH or NORTH-WEST user are seen only by users with the same tenancy.
> By
> > > changing the region of a record it can change tenancy.
> > >
> > > Presently this is broken, or at least it I think it was working
> correctly
> > > when I allowed a record with a region of null to be the GLOBAL ones. I
> > need
> > > to have this working for a demo tomorrow, so advice is welcomed on how
> > best
> > > to set this up properly.
> > >
> > > My base class that controls all this here:
> > >
> > >
> >
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> > >
> > > The other small glitch is that a person record created in the process
> of
> > > creating a participant doesn't get assigned a region automatically. I
> > have
> > > a work-around for that in place at present, anything that has a null
> > region
> > > gets presented as having a global tenancy.
> > >
> > >
> > > Thanks
> > >
> > > Steve Cameron
> > >
> >
>
Re: Application Tenancy
Posted by Stephen Cameron <st...@gmail.com>.
Hi Dan,
I did not explain it that well sorry.
I want to get rid of nulls completely, the fact that I do handle them is
just a work-around for the fact that they are still being created, but only
for People. That is, if a new Participant is registered it looks to see if
there is an existing Person with the same details then adds a new one if
not present (a single Person can be a Participant and/or a Volunteer). The
Participant is getting its region set in setUpdatedBy() but the Person is
not, I need to debug this.
As general interest is handling such things via such a service better, that
is to avoid injecting services into entities if possible?
Last minute tweeks aren't the best idea, but the tests that I do have are
proving their value. These particular issues are probably a result of no
integration tests yet.
Thanks
On Thu, Nov 26, 2015 at 8:09 AM, Dan Haywood <da...@haywood-associates.co.uk>
wrote:
> Hi Steve,
>
> Not sure I follow quite all the ins-and-outs of this, but what could well
> be of use is the optional ApplicationTenancyPathEvaluator domain
> service[1]. If an implementation is registered (on the classpath), then
> the security module will delegate to this [2] in order to determine who
> gets to see/edit what.
>
> From what I did follow, it sounds like you need to treat objects with a
> null region in a particular way? If so, then hopefully you can put this
> "special case" logic in an implementation of said service.
>
> HTH
> Dan
>
>
>
> [1]
>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
> [2]
>
> https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
>
>
> On 25 November 2015 at 20:25, Stephen Cameron <st...@gmail.com>
> wrote:
>
> > Hi,
> >
> > I have a problem with Application Tenancies not working the way I want, I
> > want to drive it off a field 'region', such that a person is assigned a
> > tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the
> regions
> > that they are working in too, so when they create a record their region
> > gets assigned to the new record and that controls who else can see the
> > record.
> >
> > This mostly works, but there is one small glitch. The main problem I have
> > is setting it up so that region is non-null and any records created by a
> > GLOBAL tenancy user are seen by all users, while those created by a
> NORTH,
> > SOUTH or NORTH-WEST user are seen only by users with the same tenancy. By
> > changing the region of a record it can change tenancy.
> >
> > Presently this is broken, or at least it I think it was working correctly
> > when I allowed a record with a region of null to be the GLOBAL ones. I
> need
> > to have this working for a demo tomorrow, so advice is welcomed on how
> best
> > to set this up properly.
> >
> > My base class that controls all this here:
> >
> >
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
> >
> > The other small glitch is that a person record created in the process of
> > creating a participant doesn't get assigned a region automatically. I
> have
> > a work-around for that in place at present, anything that has a null
> region
> > gets presented as having a global tenancy.
> >
> >
> > Thanks
> >
> > Steve Cameron
> >
>
Re: Application Tenancy
Posted by Dan Haywood <da...@haywood-associates.co.uk>.
Hi Steve,
Not sure I follow quite all the ins-and-outs of this, but what could well
be of use is the optional ApplicationTenancyPathEvaluator domain
service[1]. If an implementation is registered (on the classpath), then
the security module will delegate to this [2] in order to determine who
gets to see/edit what.
>From what I did follow, it sounds like you need to treat objects with a
null region in a particular way? If so, then hopefully you can put this
"special case" logic in an implementation of said service.
HTH
Dan
[1]
https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/dom/tenancy/ApplicationTenancyPathEvaluator.java
[2]
https://github.com/isisaddons/isis-module-security/blob/master/dom/src/main/java/org/isisaddons/module/security/facets/TenantedAuthorizationFacetFactory.java#L72
On 25 November 2015 at 20:25, Stephen Cameron <st...@gmail.com>
wrote:
> Hi,
>
> I have a problem with Application Tenancies not working the way I want, I
> want to drive it off a field 'region', such that a person is assigned a
> tenancy of GLOBAL, NORTH, SOUTH, NORTH-WEST and these are also the regions
> that they are working in too, so when they create a record their region
> gets assigned to the new record and that controls who else can see the
> record.
>
> This mostly works, but there is one small glitch. The main problem I have
> is setting it up so that region is non-null and any records created by a
> GLOBAL tenancy user are seen by all users, while those created by a NORTH,
> SOUTH or NORTH-WEST user are seen only by users with the same tenancy. By
> changing the region of a record it can change tenancy.
>
> Presently this is broken, or at least it I think it was working correctly
> when I allowed a record with a region of null to be the GLOBAL ones. I need
> to have this working for a demo tomorrow, so advice is welcomed on how best
> to set this up properly.
>
> My base class that controls all this here:
>
> https://github.com/Stephen-Cameron-Data-Services/isis-chats/blob/master/dom/src/main/java/au/com/scds/chats/dom/AbstractChatsDomainEntity.java
>
> The other small glitch is that a person record created in the process of
> creating a participant doesn't get assigned a region automatically. I have
> a work-around for that in place at present, anything that has a null region
> gets presented as having a global tenancy.
>
>
> Thanks
>
> Steve Cameron
>