Ich verwende JPA (EclipseLink) und Spring. Angenommen, ich habe eine einfache Entität mit einer automatisch generierten ID:
@Entity
public class ABC implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
// ...
}
In meiner DAO-Klasse habe ich eine Einfügemethode, die persist()
diese Entität aufruft . Ich möchte, dass die Methode die generierte ID für die neue Entität zurückgibt, aber wenn ich sie teste, wird sie 0
stattdessen zurückgegeben.
public class ABCDao {
@PersistenceContext
EntityManager em;
@Transactional(readOnly=false)
public int insertABC(ABC abc) {
em.persist(abc);
// I WANT TO RETURN THE AUTO-GENERATED ID OF abc
// HOW CAN I DO IT?
return abc.id; // ???
}
}
Ich habe auch eine Serviceklasse, die das DAO umschließt, wenn das einen Unterschied macht:
public class ABCService {
@Resource(name="ABCDao")
ABCDao abcDao;
public int addNewABC(ABC abc) {
return abcDao.insertABC(abc);
}
}
Antworten:
Die ID wird garantiert nur zur Spülzeit generiert. Durch das Fortbestehen einer Entität wird sie nur an den Persistenzkontext "angehängt". Spülen Sie also entweder den Entitätsmanager explizit:
oder geben Sie die Entität selbst anstelle ihrer ID zurück. Wenn die Transaktion endet, erfolgt der Flush, und Benutzer der Entität außerhalb der Transaktion sehen somit die generierte ID in der Entität.
quelle
@GeneratedValue
- was auch immer das beinhaltetinsertABC
erstellt ein neues Objekt? Oder das alte modifizieren?Überprüfen Sie, ob die @ GenerationValue-Notation in Ihrer Entitätsklasse vorhanden ist. Dadurch wird JPA über das automatisch generierte Verhalten Ihrer Entitätseigenschaft informiert
quelle
So habe ich es gemacht:
quelle
Sie können auch GenerationType.TABLE anstelle von IDENTITY verwenden, die erst nach dem Einfügen verfügbar ist.
quelle
Eine weitere mit 4.0 kompatible Option:
Bevor Sie die Änderungen festschreiben, können Sie die neuen
CayenneDataObject
Objekte aus der dem Kontext zugeordneten Sammlung wie folgt wiederherstellen :Greifen Sie dann auf die
ObjectId
für jeden in der Sammlung zu, wie:Schließlich können Sie unter den Werten iterieren, wobei die generierte ID normalerweise der erste der Werte (für einen einzelnen Spaltenschlüssel) in der von zurückgegebenen Map
getIdSnapshot()
ist. Sie enthält auch die Spaltennamen, die der PK zugeordnet sind als Schlüssel:quelle
So habe ich es gemacht. Du kannst es versuchen
quelle
quelle
em.flush()
nichtem.refresh(abc)
.