22

This question is essentially the opposite of this one.

I have a method like so:

public boolean isVacant() {
    return getEmployeeNum() != null && getEmployeeNum().equals("00000000");
}

When I load it up, Hibernate is complaining that I have no attribute called vacant. But I don't want an attribute called vacant - I have no need to store that data - it's simply logic.

Hibernate says:

org.hibernate.PropertyNotFoundException: Could not find a setter for property vacant in class com.mycomp.myclass...

Is there an annotation I can add to my isVacant() method to make Hibernate ignore it?

Community
  • 1
  • 1
corsiKa
  • 81,495
  • 25
  • 153
  • 204

3 Answers3

43

Add @Transient to the method then Hibernate should ignore it.

To quote the Hibernate Documentation:

Every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as @Transient.

Pavel
  • 4,912
  • 7
  • 49
  • 69
RNJ
  • 15,272
  • 18
  • 86
  • 131
3

RNJ is correct, but I might add why this happens:

I'm guessing that you have annotated the getters of your persistent class. The prefixes used by java beans are "set" and "get", which are used do read and write to variables, but there is also the prefix "is", which is used for boolean values (instead of "get"). When Hibernate sees your getter-annotated persistent class, and finds a method "isVacant", it assumes that there is a property "vacant", and assumes that there is a "set"-method as well.

So, to fix it, you could either add the @Transient annotation, or you could change the name of your method to something that doesn't start with "is". I don't think this would be a problem if your class was annotated on the fields, instead of the get-methods.

Tobb
  • 11,850
  • 6
  • 52
  • 77
  • 4
    The problem with renaming the method, though, is that that too breaks convention. By convention, methods that return booleans (whether or not they are members) start with is or has. Consider the `java.util.Collection` method `isEmpty()` - most Collections do not store whether they are empty or not - they compare their size to 0. (This isn't true for all collections, for example `ConcurrentLinkedQueue`, but it is for most, so much so that `AbstractCollection` implements it as such.) – corsiKa Sep 10 '12 at 21:33
0

Many frameworks (like Hibernate and Drools) are smart enough understand that Boolean variables need to be accessed by "is" instead of "get". But they don't always understand perfectly, and that is when "interesting" problems can develop. Or, worse yet, the different frameworks interpret the methods slightly differently, and they are supposed to work together.

BTW, the @Transient solution is not guaranteed to solve all your problems. Most notably, say that you are adding it to a toString() that returns a huge and complex object. You might be getting a stack overflow not because the method is huge and complex, or even because all the sub-obejcts have their own toString() methods, but because your structure has circular structures. That is what causes the stack overflows.

Tihamer
  • 935
  • 10
  • 8
  • Slight clarification: boolean primitives gets the isFiledName() treatment. The Boolean objects, however, will get the getFieldName treatment since Boolean objects can be null can be null. – ScrappyDev Apr 28 '22 at 13:25