Ich habe mein Datenmodell mit JPA aufgebaut und verwende den EntityManager 3 von Hibernate für den Zugriff auf die Daten. Ich habe HSQLDB zum Testen verwendet (Junit). Ich verwende diese Konfiguration für andere Klassen und habe keine Probleme gehabt.
Der letzte Tabellenstapel verwendet jedoch einen zusammengesetzten Schlüssel als Primärschlüssel, und ich bin nicht in der Lage, die ausgefüllte Zeile aus der Datenbank abzurufen, wenn sie implementiert ist. Ich erhalte keine Fehlermeldung, die Abfrage gibt einfach Null-Objekte zurück.
Wenn ich zum Beispiel (mit jsql) "FROM Order o" abfrage, um eine Liste aller Bestellungen in der Tabelle zurückzugeben, hat meine list.size() die richtige Anzahl von Elementen (2), aber die Elemente sind null.
Ich hoffe, dass jemand, der einen schärferen Blick hat als ich, erkennen kann, was ich falsch mache. Vielen Dank im Voraus!
Die (vereinfachten) Tabellen sind wie folgt definiert:
CREATE TABLE member (
member_id INTEGER NOT NULL IDENTITY PRIMARY KEY);
CREATE TABLE orders (
orders_id INTEGER NOT NULL,
member_id INTEGER NOT NULL,
PRIMARY KEY(orders_id, member_id));
ALTER TABLE orders
ADD CONSTRAINT fk_orders_member
FOREIGN KEY (member_id) REFERENCES member(member_id);
Die Entitäts-POJOs werden definiert durch:
@Entity
public class Member extends Person implements Model<Integer>{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="MEMBER_ID", nullable=false)
private Integer memberId;
@OneToMany(fetch=FetchType.LAZY, mappedBy="member", cascade=CascadeType.ALL)
private Set<Order> orderList;
}
@Entity
@Table(name="ORDERS")
@IdClass(OrderPK.class)
public class Order extends GeneralTableInformation implements Model<Integer>{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ORDERS_ID", nullable=false)
private Integer orderId;
@Id
@Column(name="MEMBER_ID", nullable=false)
private Integer memberId;
@ManyToOne(optional=false, fetch=FetchType.LAZY)
@JoinColumn(name="MEMBER_ID", nullable=false)
private Member member;
@OneToMany(mappedBy="order", fetch=FetchType.LAZY)
private Set<Note> noteList;
}
OrderPK definiert einen Standardkonstruktor und 2 Eigenschaften (orderId, memberId) zusammen mit ihren get/set-Methoden.
public class OrderPK implements Serializable {
private static final long serialVersionUID = 1L;
private Integer orderId;
private Integer memberId;
public OrderPK() {}
public OrderPK(Integer orderId, Integer memberId) {
this.orderId = orderId;
this.memberId = memberId;
}
/**Getters/Setters**/
@Override
public int hashCode() {
return orderId.hashCode() + memberId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof OrderPK))
return false;
OrderPK other = (OrderPK) obj;
if (memberId == null) {
if (other.memberId != null) return false;
} else if (!memberId.equals(other.memberId))
return false;
if (orderId == null) {
if (other.orderId != null) return false;
} else if (!orderId.equals(other.orderId))
return false;
return true;
}
}
(Entschuldigung für die Länge)
der EntityManager wird in einer abstrakten Klasse instanziiert, die dann von meinen anderen DAOs erweitert wird
protected EntityManager em;
@PersistenceContext
public void setEntityManager(EntityManager em) {
this.em = em;
}
und wird durch eine Konfigurationsdatei für den Federkontext konfiguriert
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="jpaAdapter">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
</bean>
Meine Testklasse
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class OrderDaoTest {
@Autowired
protected OrderDao dao = null;
@Test
public void findAllOrdersTest() {
List<Order> ol = dao.findAll();
assertNotNull(ol); //pass
assertEquals(2, ol.size(); //pass
for (Order o : ol) {
assertNotNull(o); //fail
...
}
}
}
Wenn ich den Composite-Schlüssel aus der Klasse Order entferne, kann ich Daten abrufen. Ich bin mir nicht sicher, was ich mit meiner Zuordnung oder Konfiguration falsch mache. Jede Hilfe wird sehr geschätzt.