3

Is it possible to avoid setter for primary key with Hibernate XML mapping configuration? When annotations are used you don't have to have setter method declared. See example. I'm using Hibernate version 4.1.2.

  1. XML based configuration

    public class Entity {
        private Integer id;
    
        public Integer getId() {
            return id;
        }
    }
    
    <class name="Language" table="language">
        <id name="id" column="id">
            <generator class="native" />
        </id>
    </class>
    

    While initializing Hibernate exception is thrown

    Caused by: org.hibernate.PropertyNotFoundException: Could not find a setter for property id in class net.kreuzman.eshop.core.domain.l10n.Language
        at org.hibernate.property.BasicPropertyAccessor.createSetter(BasicPropertyAccessor.java:252)
        at org.hibernate.property.BasicPropertyAccessor.getSetter(BasicPropertyAccessor.java:245)
        at org.hibernate.mapping.Property.getSetter(Property.java:325)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertySetter(PojoEntityTuplizer.java:444)
        at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:182)
        at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82)
    ... 49 more
    
  2. Annotation based configuration

    @Entity
    @Table(name="entity")
    public class Entity {
        @Id
        @Column(name="id")
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Integer id;
    
            public Integer getId() {
                 return id;
            }
    }
    

This works well.

michal.kreuzman
  • 12,170
  • 10
  • 58
  • 70
  • No, you need a setter - what is the issue with that? – Woody Apr 26 '12 at 13:30
  • 1
    @Woody I don't want to declare setter for member which should be never changed by application. Declaring it as `private` seems not nice to me. – michal.kreuzman Apr 26 '12 at 13:31
  • I think you need setter, but can't you declare it non-public? (e.g. `protected`). This is just speculation. I am not expert. – Boris Strandjev Apr 26 '12 at 13:32
  • @Boris Strandjev yes I can declare it non-public but for what? It will be never used. Seems awkward to me. – michal.kreuzman Apr 26 '12 at 13:33
  • @krocan - you are wrong. It will be used, but through reflection. If this seems awkward to you, why declaring a private field without setter in the annotation case does not? – Boris Strandjev Apr 26 '12 at 13:40

3 Answers3

4

You can set the access type to field, which will achieve the same thing as putting the annotation on the field.

<class name="Language" table="language">
    <id name="id" column="id" access="field">
        <generator class="native" />
    </id>
</class>
beny23
  • 34,390
  • 5
  • 82
  • 85
0

I think hibernate creates objects via reflection (Class.newInstance()) which is why it need the no args constructor. That way - i don't see how its possible to leave out a setter for a used property. U can mark unused fields as @Transient but thats it.

hburde
  • 1,441
  • 11
  • 6
  • Yes you right Hibernate creates objects via reflection and you can also setup private member via reflection so you don't need setter method. Anyway it works while using annotations see question. – michal.kreuzman Apr 26 '12 at 13:38
  • Opps - yep - i used this only once some time ago. – hburde Apr 26 '12 at 13:55
0
@GeneratedValue(strategy = GenerationType.IDENTITY)

instead of auto

Bohemian
  • 412,405
  • 93
  • 575
  • 722