1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package ch.elca.el4j.services.persistence.generic.dto;
19
20 import javax.persistence.Column;
21 import javax.persistence.Id;
22 import javax.persistence.MappedSuperclass;
23 import javax.persistence.Transient;
24
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import ch.elca.el4j.util.codingsupport.ObjectUtils;
29
30
31
32
33
34
35
36
37
38 @MappedSuperclass
39 public abstract class AbstractStringKeyIntOptimisticLockingDto
40 extends AbstractIntOptimisticLockingDto
41 implements PrimaryKeyOptimisticLockingObject {
42
43
44
45
46 private static Logger s_logger = LoggerFactory.getLogger(AbstractStringKeyIntOptimisticLockingDto.class);
47
48
49
50
51 private String m_key;
52
53
54
55
56 private boolean m_transientHashCodeLeaked = false;
57
58
59
60
61 @Transient
62 public boolean isKeyNew() {
63 return m_key == null;
64 }
65
66
67
68
69 @Id
70 @Column(name = "KEYID")
71 public String getKey() {
72 return m_key;
73 }
74
75
76
77
78 @Transient
79 public Object getKeyAsObject() {
80 return isKeyNew() ? null : getKey();
81 }
82
83
84
85
86 public void setKey(String key) {
87 m_key = key;
88 }
89
90
91
92
93 public void setKey(Object keyObject) {
94 String key = (keyObject == null) ? null : keyObject.toString();
95 setKey(key);
96 }
97
98
99
100
101 public int hashCode() {
102 if (m_key == null) {
103 m_transientHashCodeLeaked = true;
104 return super.hashCode();
105 } else {
106 if (m_transientHashCodeLeaked) {
107 s_logger.error("hashCode() has be called once on transient state and once on persistent state "
108 + "of object '" + this.toString() + "' (" + getClass().toString() + "). "
109 + "This can happen if you insert a transient object into a collection and persist them afterwards. "
110 + "Save the objects before you insert them into a collection!");
111 }
112 return m_key.hashCode();
113 }
114 }
115
116
117
118
119 public boolean equals(Object obj) {
120 if (this == obj) {
121 return true;
122 }
123 if (obj instanceof AbstractStringKeyIntOptimisticLockingDto) {
124 AbstractStringKeyIntOptimisticLockingDto other
125 = (AbstractStringKeyIntOptimisticLockingDto) obj;
126 return ObjectUtils.nullSaveEquals(m_key, other.m_key);
127 } else {
128 return false;
129 }
130 }
131 }