datasetsection-allow-nonunique-names

Bug #724165 reported by jason.p.pickering on 2011-02-24
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DHIS
Undecided
Morten Olav Hansen

Bug Description

Data set sections can currently be assigned non-unique names. Perhaps this is a design feature, but it does not seem to make a whole lot of sense. Would suggest to require each section to have a unique name.
When dataset sections with identical names are attempted to be deleted, an exception occurs.

* ERROR 09:54:44,216 Error while executing action (ExceptionInterceptor.java [17
109727@qtp-7408068-94])
org.hibernate.NonUniqueResultException: query did not return a unique result: 2
        at org.hibernate.impl.AbstractQueryImpl.uniqueElement(AbstractQueryImpl.
java:868)
        at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:369)
        at org.hisp.dhis.dataset.hibernate.HibernateSectionStore.getSectionByNam
e(HibernateSectionStore.java:89)
        at org.hisp.dhis.dataset.DefaultSectionService.getSectionByName(DefaultS
ectionService.java:98)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
on(AopUtils.java:309)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJo
inpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:150)
        at org.springframework.transaction.interceptor.TransactionInterceptor.in
voke(TransactionInterceptor.java:110)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
cAopProxy.java:202)
        at $Proxy19.getSectionByName(Unknown Source)
        at org.hisp.dhis.dataset.action.section.ValidateSectionAction.execute(Va
lidateSectionAction.java:102)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultA
ctionInvocation.java:441)
        at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(Defa
ultActionInvocation.java:280)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:243)
        at org.hisp.dhis.webportal.interceptor.XWorkPortalUserInterceptor.interc
ept(XWorkPortalUserInterceptor.java:82)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.webportal.interceptor.XWorkPortalModuleInterceptor.inte
rcept(XWorkPortalModuleInterceptor.java:85)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.webportal.interceptor.XWorkPortalMenuInterceptor.interc
ept(XWorkPortalMenuInterceptor.java:91)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.webportal.interceptor.XWorkPortalParamsInterceptor.inte
rcept(XWorkPortalParamsInterceptor.java:117)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.ContextInterceptor.intercept(ContextInterce
ptor.java:70)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.StyleInterceptor.intercept(StyleInterceptor
.java:107)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.SystemSettingInterceptor.intercept(SystemSe
ttingInterceptor.java:94)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.DisplayPropertyInterceptor.intercept(Displa
yPropertyInterceptor.java:90)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.SortOrderInterceptor.intercept(SortOrderInt
erceptor.java:124)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.security.intercept.XWorkSecurityInterceptor.intercept(X
WorkSecurityInterceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.I18nInterceptor.intercept(I18nInterceptor.j
ava:141)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(Cha
iningInterceptor.java:126)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept
(ParametersInterceptor.java:195)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept
(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.inter
cept(StaticParametersInterceptor.java:179)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.hisp.dhis.interceptor.ExceptionInterceptor.intercept(ExceptionInt
erceptor.java:98)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionI
nvocation.java:237)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.j
ava:52)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.jav
a:488)
        at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatc
her.java:395)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1157)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:368)
        at org.hisp.dhis.security.filter.RequiredLoginFilter.doFilter(RequiredLo
ginFilter.java:129)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:380)
        at org.hisp.dhis.security.filter.AutomaticAccessFilter.doFilter(Automati
cAccessFilter.java:112)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:380)
        at org.springframework.security.web.authentication.logout.LogoutFilter.d
oFilter(LogoutFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:380)
        at org.springframework.security.web.authentication.AbstractAuthenticatio
nProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:380)
        at org.springframework.security.web.context.SecurityContextPersistenceFi
lter.doFilter(SecurityContextPersistenceFilter.java:79)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.
doFilter(FilterChainProxy.java:380)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChai
nProxy.java:169)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(D
elegatingFilterProxy.java:237)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(Delegat
ingFilterProxy.java:167)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1157)
        at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.do
FilterInternal(OpenSessionInViewFilter.java:198)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerR
equestFilter.java:76)
        at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(Servlet
Handler.java:1157)
        at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:3
88)
        at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.jav
a:216)
        at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:1
82)
        at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:7
65)
        at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:440)

        at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:1
52)
        at org.mortbay.jetty.Server.handle(Server.java:326)
        at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:54
2)
        at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnectio
n.java:943)
        at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
        at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
        at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
        at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.ja
va:410)
        at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.j
ava:582)

Changed in dhis2:
milestone: none → 2.2
assignee: nobody → Morten Olav Hansen (mortenoh)
assignee: Morten Olav Hansen (mortenoh) → nobody

Could not reproduce this but I see we accept equal names on sections belonging to the same data set.

We need to put in place proper validation for denying equal names on sections belonging to the same data set when adding and updating sections.

Changed in dhis2:
assignee: nobody → Morten Olav Hansen (mortenoh)
status: New → Confirmed

Steps to reproduce.
1) Create a dataset with two category combos.
2) Add a data set section from the first catcombo named "Test." Save the section.
3) Add a data set section to the same dataset with the second catcombo named "Test". Save the section.
4) Attempt to delete the data set section.

I was unable to reproduce this on MySQL.

Download full text (10.8 KiB)

Can you pls check if there is a uniqueness constraint on section.name in the
database you are using when it fails? If so it should be removed.

On Sun, Mar 13, 2011 at 8:16 AM, jason.p.pickering <
<email address hidden>> wrote:

> Steps to reproduce.
> 1) Create a dataset with two category combos.
> 2) Add a data set section from the first catcombo named "Test." Save the
> section.
> 3) Add a data set section to the same dataset with the second catcombo
> named "Test". Save the section.
> 4) Attempt to delete the data set section.
>
> I was unable to reproduce this on MySQL.
>
> --
> You received this bug notification because you are a member of DHIS 2
> coordinators, which is the registrant for DHIS.
> https://bugs.launchpad.net/bugs/724165
>
> Title:
> datasetsection-allow-nonunique-names
>
> Status in DHIS 2 - District Health Information Software:
> Confirmed
>
> Bug description:
> Data set sections can currently be assigned non-unique names. Perhaps this
> is a design feature, but it does not seem to make a whole lot of sense.
> Would suggest to require each section to have a unique name.
> When dataset sections with identical names are attempted to be deleted, an
> exception occurs.
>
> * ERROR 09:54:44,216 Error while executing action
> (ExceptionInterceptor.java [17
> 109727@qtp-7408068-94])
> org.hibernate.NonUniqueResultException: query did not return a unique
> result: 2
> at
> org.hibernate.impl.AbstractQueryImpl.uniqueElement(AbstractQueryImpl.
> java:868)
> at
> org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:369)
> at
> org.hisp.dhis.dataset.hibernate.HibernateSectionStore.getSectionByNam
> e(HibernateSectionStore.java:89)
> at
> org.hisp.dhis.dataset.DefaultSectionService.getSectionByName(DefaultS
> ectionService.java:98)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
> at java.lang.reflect.Method.invoke(Unknown Source)
> at
> org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
> on(AopUtils.java:309)
> at
> org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJo
> inpoint(ReflectiveMethodInvocation.java:183)
> at
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
> ReflectiveMethodInvocation.java:150)
> at
> org.springframework.transaction.interceptor.TransactionInterceptor.in
> voke(TransactionInterceptor.java:110)
> at
> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
> ReflectiveMethodInvocation.java:172)
> at
> org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
> cAopProxy.java:202)
> at $Proxy19.getSectionByName(Unknown Source)
> at
> org.hisp.dhis.dataset.action.section.ValidateSectionAction.execute(Va
> lidateSectionAction.java:102)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
> at sun.reflec...

Download full text (21.9 KiB)

Seems to be no constraint on section.name.

CREATE TABLE section
(
  sectionid integer NOT NULL,
  "name" character varying(255) NOT NULL,
  datasetid integer,
  sortorder integer,
  CONSTRAINT section_pkey PRIMARY KEY (sectionid),
  CONSTRAINT fk756f7ee5e8fa755b FOREIGN KEY (datasetid)
      REFERENCES dataset (datasetid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE section OWNER TO postgres;

I was unable to reproduce this on Postgres now (using 2996). I can
still add sections with the same name, but they are deleted properly.

2011/3/13 Lars Helge Øverland <email address hidden>:
> Can you pls check if there is a uniqueness constraint on section.name in the
> database you are using when it fails? If so it should be removed.
>
> On Sun, Mar 13, 2011 at 8:16 AM, jason.p.pickering <
> <email address hidden>> wrote:
>
>> Steps to reproduce.
>> 1) Create a dataset with two category combos.
>> 2) Add a data set section from the first catcombo named "Test." Save the
>> section.
>> 3) Add a data set section to the same dataset with the second catcombo
>> named "Test". Save the section.
>> 4) Attempt to delete the data set section.
>>
>> I was unable to reproduce this on MySQL.
>>
>> --
>> You received this bug notification because you are a member of DHIS 2
>> coordinators, which is the registrant for DHIS.
>> https://bugs.launchpad.net/bugs/724165
>>
>> Title:
>>  datasetsection-allow-nonunique-names
>>
>> Status in DHIS 2 - District Health Information Software:
>>   Confirmed
>>
>> Bug description:
>>  Data set sections can currently be assigned non-unique names. Perhaps this
>> is a design feature, but it does not seem to make a whole lot of sense.
>> Would suggest to require each section to have a unique name.
>>  When dataset sections with identical names are attempted to be deleted, an
>> exception occurs.
>>
>>  * ERROR 09:54:44,216 Error while executing action
>> (ExceptionInterceptor.java [17
>>  109727@qtp-7408068-94])
>>  org.hibernate.NonUniqueResultException: query did not return a unique
>> result: 2
>>          at
>> org.hibernate.impl.AbstractQueryImpl.uniqueElement(AbstractQueryImpl.
>>  java:868)
>>          at
>> org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:369)
>>          at
>> org.hisp.dhis.dataset.hibernate.HibernateSectionStore.getSectionByNam
>>  e(HibernateSectionStore.java:89)
>>          at
>> org.hisp.dhis.dataset.DefaultSectionService.getSectionByName(DefaultS
>>  ectionService.java:98)
>>          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>          at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>>          at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>>          at java.lang.reflect.Method.invoke(Unknown Source)
>>          at
>> org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
>>  on(AopUtils.java:309)
>>          at
>> org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJo
>>  inpoint(ReflectiveMethodInvocation.java:183)
>>          at
>> org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(
>>  ReflectiveMethodInvocation.java:150)
>>...

Good. Then we will add the validation, check back if you experience the
deletion issue again.

On Sun, Mar 13, 2011 at 8:53 AM, jason.p.pickering <
<email address hidden>> wrote:

> Seems to be no constraint on section.name.
>
> CREATE TABLE section
> (
> sectionid integer NOT NULL,
> "name" character varying(255) NOT NULL,
> datasetid integer,
> sortorder integer,
> CONSTRAINT section_pkey PRIMARY KEY (sectionid),
> CONSTRAINT fk756f7ee5e8fa755b FOREIGN KEY (datasetid)
> REFERENCES dataset (datasetid) MATCH SIMPLE
> ON UPDATE NO ACTION ON DELETE NO ACTION
> )
> WITH (
> OIDS=FALSE
> );
> ALTER TABLE section OWNER TO postgres;
>
> I was unable to reproduce this on Postgres now (using 2996). I can
> still add sections with the same name, but they are deleted properly.
>
> 2011/3/13 Lars Helge Øverland <email address hidden>:
> > Can you pls check if there is a uniqueness constraint on section.name in
> the
> > database you are using when it fails? If so it should be removed.
> >
> > On Sun, Mar 13, 2011 at 8:16 AM, jason.p.pickering <
> > <email address hidden>> wrote:
> >
> >> Steps to reproduce.
> >> 1) Create a dataset with two category combos.
> >> 2) Add a data set section from the first catcombo named "Test." Save the
> >> section.
> >> 3) Add a data set section to the same dataset with the second catcombo
> >> named "Test". Save the section.
> >> 4) Attempt to delete the data set section.
> >>
> >> I was unable to reproduce this on MySQL.
> >>
> >> --
> >> You received this bug notification because you are a member of DHIS 2
> >> coordinators, which is the registrant for DHIS.
> >> https://bugs.launchpad.net/bugs/724165
> >>
> >> Title:
> >> datasetsection-allow-nonunique-names
> >>
> >> Status in DHIS 2 - District Health Information Software:
> >> Confirmed
> >>
> >> Bug description:
> >> Data set sections can currently be assigned non-unique names. Perhaps
> this
> >> is a design feature, but it does not seem to make a whole lot of sense

We need to this constraint to the db as well.

 unique-key="key_sectionnamedataset"

Morten Olav Hansen (mortenoh) wrote :

This is now a constraint on the DB. The validation was fixed in an earlier release (there was a bug with remote validation).

DataSet + Section should now be unique.

Changed in dhis2:
status: Confirmed → Fix Committed
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers