When I create a bidirectional many to one association, and then delete an element from the middle of the list, the delete works (eg, the element row is removed from the SQL table), but the other elements associated index are not updated. Eg, if I had 3 elements with index 0,1,2 and delete the second element, I still have element 0 and 2 that have index 0 and 2.
This later causes a Null Pointer exception when loading the list in a next request. Apparently, Grails thinks that the middle element is still there (but null).
If I change the relationship to a unidirectional one, Grails uses a join table (as per Hibernate recommandations), and everything works as expected. Indexs are updated etc.
But since a bidirectional many to one is the most common association, this should really be fixed. It is perfectly supported by Hibernate, so I don't know why it fails. While this bug is not fixed, using Lists in bidirectional relationships won't work. Again, the kind of bug that can confuse newcomers to Grails 
The code I used was a simple:
account.removeFromArticles(article)
article.delete()
This is probably closely related to http://jira.codehaus.org/browse/GRAILS-1819
. I just create a new JIRA because the symptoms are not exactly the same. In particular, the delete works in my case, only the indexes are messed up after.
Ok, so Hibernate supports this with the following mapping. All that is needed is to tell GORM to use this mapping. This will also solve bug 1819 (and many other) regarding bidirectional lists, as currently it does not work at all.
For reference,
http://www.hibernate.org/hib_docs/annotations/reference/en/html_single/#entity-hibspec-collection-extratype
is a must read (section 2.4.6.2.3. Bidirectional association with indexed collections).
PS: on the following mapping "position" should be changed for something ending with _idx to follow GORM conventions
import javax.persistence.*
import org.hibernate.annotations.*
@Entity
@Table(name="faq_section")
class FaqSection
{
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
Long id
@Version
Long version
String title
@OneToMany(cascade = [javax.persistence.CascadeType.ALL], targetEntity = FaqElement.class)
@JoinColumn(name = "section_id", nullable = false)
@IndexColumn(name = "position", base = 0)
List elements
}
import javax.persistence.*
import org.hibernate.annotations.*
@Entity
@Table(name="faq_element")
class FaqElement
{
@Id
@GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
Long id
@Version
Long version
String question
String answer
@ManyToOne
@JoinColumn(name = "section_id", nullable = false, updatable = false, insertable = false)
FaqSection section
static constraints =
{ question(size: 1..500) answer(size: 1..5000) }}