GORM not merging right

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

GORM not merging right

Felipe Cypriano
Hello,

I'm having problem with merge operation. I've created a LoadTestDataBootStrap to load to the test database some data needed in the integrations test. For one of my domain classes the merge method is always inserting new rows in the database, see some code within the bootstrap:

    private void loadClienteData() {
        def uf = UF.get('ES')
        def clienteMap = [
            [id: 100, nome: 'JUnit', uf: uf, tipoPessoa: PessoaTipo.JURIDICA],
            [id: 101, nome: 'JU Confecção Ltda', tipoPessoa: PessoaTipo.JURIDICA],
            [id: 102, nome: 'Confecções zzz', tipoPessoa: PessoaTipo.JURIDICA]
        ]
        def instances = []
        clienteMap.each {
            createInstance(it, new Cliente(), instances)
        }
        saveInstances(instances)
    }

    private def createInstance = {map, instance, list ->
        instance.id = map.id
        instance.properties = map
        list << instance
    }

    private def saveInstances = { instances ->
        instances.each { entity ->
            entity.merge(flush: true)
        }
    }

I've created the createInstance closure because the id property isn't getting setted using new Cliente(id: 100, nome: 'JUnit'). The Cliente class is POJO mapped with JPA annotations, but I'm using only hibernate no JPA plugin.

In the same script I've other methods to fill other tables which works without problem using the very same createInstance and saveInstances closures. When persisting Cliente the id is auto generated and isn't the id that I setted, the strategy is sequence.

Why merge is always creating new rows?

---
Felipe Marin Cypriano
Vitória - ES
Reply | Threaded
Open this post in threaded view
|

Re: GORM not merging right

Felipe Cypriano
For Cliente class (and Fornecedor class) the merging is only working after a save (an explicity insert). Both Cliente and Fornecedor extends the same abstract class CliFor and they use discriminator values to indentify each concrete class.

So in the database I've one table called CLIFOR and one column called CF which indicates if the record id a Cliente or a Fornecedor.

@DiscriminatorColumn(name = "CF", discriminatorType = DiscriminatorType.STRING)
abstract class Clifor //....
@DiscriminatorValue("C")
class Cliente extends CliFor //...
@DiscriminatorValue("F")
class Fornecedor extends CliFor...

If I explicity set the id to a new id and call merge the record is inserted but the id that I setted is not used and a sequence generated id is instead:
def c = new Cliente()
c.id = 123 // this is a new id
c.merge(flush: true)

Shoudn't the merge use the id that I setted instead of a sequence one, like it does with all other classes (which also uses sequence strategy for id)?

---
Felipe Marin Cypriano
Vitória - ES


On Mon, May 25, 2009 at 1:57 PM, Felipe Cypriano <[hidden email]> wrote:
Hello,

I'm having problem with merge operation. I've created a LoadTestDataBootStrap to load to the test database some data needed in the integrations test. For one of my domain classes the merge method is always inserting new rows in the database, see some code within the bootstrap:

    private void loadClienteData() {
        def uf = UF.get('ES')
        def clienteMap = [
            [id: 100, nome: 'JUnit', uf: uf, tipoPessoa: PessoaTipo.JURIDICA],
            [id: 101, nome: 'JU Confecção Ltda', tipoPessoa: PessoaTipo.JURIDICA],
            [id: 102, nome: 'Confecções zzz', tipoPessoa: PessoaTipo.JURIDICA]
        ]
        def instances = []
        clienteMap.each {
            createInstance(it, new Cliente(), instances)
        }
        saveInstances(instances)
    }

    private def createInstance = {map, instance, list ->
        instance.id = map.id
        instance.properties = map
        list << instance
    }

    private def saveInstances = { instances ->
        instances.each { entity ->
            entity.merge(flush: true)
        }
    }

I've created the createInstance closure because the id property isn't getting setted using new Cliente(id: 100, nome: 'JUnit'). The Cliente class is POJO mapped with JPA annotations, but I'm using only hibernate no JPA plugin.

In the same script I've other methods to fill other tables which works without problem using the very same createInstance and saveInstances closures. When persisting Cliente the id is auto generated and isn't the id that I setted, the strategy is sequence.

Why merge is always creating new rows?

---
Felipe Marin Cypriano
Vitória - ES

Reply | Threaded
Open this post in threaded view
|

Re: GORM not merging right

Felipe Cypriano
If I set the id manually and call merge, grails looks for an already existed id if it found one the data updated, if not a new row is inserted BUT the id is generated by the sequence and isn't the id that I want.

IMO if I set the id it must be used and the auto generated should be use only if I don't set any id at all.

Is this the normal behavior?

---
Felipe Marin Cypriano
Vitória - ES


On Mon, May 25, 2009 at 3:53 PM, Felipe Cypriano <[hidden email]> wrote:
For Cliente class (and Fornecedor class) the merging is only working after a save (an explicity insert). Both Cliente and Fornecedor extends the same abstract class CliFor and they use discriminator values to indentify each concrete class.

So in the database I've one table called CLIFOR and one column called CF which indicates if the record id a Cliente or a Fornecedor.

@DiscriminatorColumn(name = "CF", discriminatorType = DiscriminatorType.STRING)
abstract class Clifor //....
@DiscriminatorValue("C")
class Cliente extends CliFor //...
@DiscriminatorValue("F")
class Fornecedor extends CliFor...

If I explicity set the id to a new id and call merge the record is inserted but the id that I setted is not used and a sequence generated id is instead:
def c = new Cliente()
c.id = 123 // this is a new id
c.merge(flush: true)

Shoudn't the merge use the id that I setted instead of a sequence one, like it does with all other classes (which also uses sequence strategy for id)?


---
Felipe Marin Cypriano
Vitória - ES


On Mon, May 25, 2009 at 1:57 PM, Felipe Cypriano <[hidden email]> wrote:
Hello,

I'm having problem with merge operation. I've created a LoadTestDataBootStrap to load to the test database some data needed in the integrations test. For one of my domain classes the merge method is always inserting new rows in the database, see some code within the bootstrap:

    private void loadClienteData() {
        def uf = UF.get('ES')
        def clienteMap = [
            [id: 100, nome: 'JUnit', uf: uf, tipoPessoa: PessoaTipo.JURIDICA],
            [id: 101, nome: 'JU Confecção Ltda', tipoPessoa: PessoaTipo.JURIDICA],
            [id: 102, nome: 'Confecções zzz', tipoPessoa: PessoaTipo.JURIDICA]
        ]
        def instances = []
        clienteMap.each {
            createInstance(it, new Cliente(), instances)
        }
        saveInstances(instances)
    }

    private def createInstance = {map, instance, list ->
        instance.id = map.id
        instance.properties = map
        list << instance
    }

    private def saveInstances = { instances ->
        instances.each { entity ->
            entity.merge(flush: true)
        }
    }

I've created the createInstance closure because the id property isn't getting setted using new Cliente(id: 100, nome: 'JUnit'). The Cliente class is POJO mapped with JPA annotations, but I'm using only hibernate no JPA plugin.

In the same script I've other methods to fill other tables which works without problem using the very same createInstance and saveInstances closures. When persisting Cliente the id is auto generated and isn't the id that I setted, the strategy is sequence.

Why merge is always creating new rows?

---
Felipe Marin Cypriano
Vitória - ES