Używam JPA (EclipseLink) i Spring. Powiedzmy, że mam prostą jednostkę z automatycznie wygenerowanym identyfikatorem:
@Entity
public class ABC implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
// ...
}
W mojej klasie DAO mam metodę wstawiania, która wywołuje persist()
tę jednostkę. Chcę, aby metoda zwracała wygenerowany identyfikator dla nowej jednostki, ale kiedy ją testuję, zwraca 0
zamiast tego.
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; // ???
}
}
Mam też klasę usług, która otacza DAO, jeśli to robi różnicę:
public class ABCService {
@Resource(name="ABCDao")
ABCDao abcDao;
public int addNewABC(ABC abc) {
return abcDao.insertABC(abc);
}
}
Odpowiedzi:
Gwarantuje się, że identyfikator zostanie wygenerowany tylko w czasie usuwania. Utrwalanie jednostki sprawia, że jest ona tylko „przywiązana” do kontekstu trwałości. Zatem albo wyczyść wyraźnie menedżera encji:
lub zwróć samą jednostkę, a nie jej identyfikator. Po zakończeniu transakcji nastąpi opróżnienie, a użytkownicy jednostki poza transakcją zobaczą wygenerowany identyfikator w jednostce.
źródło
@GeneratedValue
- cokolwiek to pociąga za sobąinsertABC
tworzy nowy obiekt? Albo zmodyfikować stary?sprawdź, czy notacja @GeneratedValue znajduje się w Twojej klasie encji, co informuje JPA o automatycznie generowanym zachowaniu właściwości encji
źródło
Oto jak to zrobiłem:
źródło
Możesz także użyć GenerationType.TABLE zamiast IDENTITY, które jest dostępne tylko po wstawieniu.
źródło
Inna opcja zgodna z 4.0:
Przed zatwierdzeniem zmian możesz odzyskać nowe
CayenneDataObject
obiekty z kolekcji skojarzonej z kontekstem, na przykład:następnie uzyskaj dostęp
ObjectId
do każdego z nich w kolekcji, na przykład:Na koniec możesz iterować pod wartościami, gdzie zwykle wygenerowany-id będzie pierwszą z wartości (dla pojedynczego klucza kolumny) w mapie zwróconej przez
getIdSnapshot()
, zawiera również nazwy kolumn powiązane z PK jako klucz (y):źródło
Tak to zrobiłem. Możesz spróbować
źródło
źródło
em.flush()
nieem.refresh(abc)
.