谢谢,让我彻底改变它。
使用: Spring Boot,Hibernate JPA
我在所有3列中创建了一个包含复合主键的链接表(event_attendee_link_program)
我在STS IDE中使用JPA工具从我的表中生成实体,它提供了以下代码。我删除了一些列以节省空间。
EventAttendee.java
@Entity
@Table(name="event_attendee")
@NamedQuery(name="EventAttendee.findAll", query="SELECT e FROM EventAttendee e")
public class EventAttendee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="attendee_id")
private long attendeeId;
//bi-directional many-to-one association to EventAttendeeLinkProgram
@OneToMany(mappedBy="eventAttendee")
private List<EventAttendeeLinkProgram> eventAttendeeLinkPrograms;
public List<EventAttendeeLinkProgram> getEventAttendeeLinkPrograms() {
return this.eventAttendeeLinkPrograms;
}
public void setEventAttendeeLinkPrograms(List<EventAttendeeLinkProgram> eventAttendeeLinkPrograms) {
this.eventAttendeeLinkPrograms = eventAttendeeLinkPrograms;
}
public EventAttendeeLinkProgram addEventAttendeeLinkProgram(EventAttendeeLinkProgram eventAttendeeLinkProgram) {
getEventAttendeeLinkPrograms().add(eventAttendeeLinkProgram);
eventAttendeeLinkProgram.setEventAttendee(this);
return eventAttendeeLinkProgram;
}
public EventAttendeeLinkProgram removeEventAttendeeLinkProgram(EventAttendeeLinkProgram eventAttendeeLinkProgram) {
getEventAttendeeLinkPrograms().remove(eventAttendeeLinkProgram);
eventAttendeeLinkProgram.setEventAttendee(null);
return eventAttendeeLinkProgram;
}
}
EventAttendeeLinkProgram.java
@Entity
@Table(name="event_attendee_link_program")
@NamedQuery(name="EventAttendeeLinkProgram.findAll", query="SELECT e FROM EventAttendeeLinkProgram e")
public class EventAttendeeLinkProgram implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private EventAttendeeLinkProgramPK id;
//bi-directional many-to-one association to EventAttendee
@ManyToOne
@JoinColumn(name="attendee_id", insertable=false, updatable=false)
private EventAttendee eventAttendee;
//bi-directional many-to-one association to EventOptionsAttendeeType
@ManyToOne
@JoinColumn(name="attendee_type_id", insertable=false, updatable=false)
private EventOptionsAttendeeType eventOptionsAttendeeType;
//bi-directional many-to-one association to EventProgram
@ManyToOne
@JoinColumn(name="program_id", insertable=false, updatable=false)
private EventProgram eventProgram;
public EventAttendeeLinkProgram() {
}
public EventAttendeeLinkProgramPK getId() {
return this.id;
}
public void setId(EventAttendeeLinkProgramPK id) {
this.id = id;
}
public EventAttendee getEventAttendee() {
return this.eventAttendee;
}
public void setEventAttendee(EventAttendee eventAttendee) {
this.eventAttendee = eventAttendee;
}
public EventOptionsAttendeeType getEventOptionsAttendeeType() {
return this.eventOptionsAttendeeType;
}
public void setEventOptionsAttendeeType(EventOptionsAttendeeType eventOptionsAttendeeType) {
this.eventOptionsAttendeeType = eventOptionsAttendeeType;
}
public EventProgram getEventProgram() {
return this.eventProgram;
}
public void setEventProgram(EventProgram eventProgram) {
this.eventProgram = eventProgram;
}
}
EventAttendeeLinkProgramPK.java
@Embeddable
public class EventAttendeeLinkProgramPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="attendee_id", insertable=false, updatable=false)
private int attendeeId;
@Column(name="attendee_type_id", insertable=false, updatable=false)
private int attendeeTypeId;
@Column(name="program_id", insertable=false, updatable=false)
private int programId;
public EventAttendeeLinkProgramPK() {
}
public int getAttendeeId() {
return this.attendeeId;
}
public void setAttendeeId(int attendeeId) {
this.attendeeId = attendeeId;
}
public int getAttendeeTypeId() {
return this.attendeeTypeId;
}
public void setAttendeeTypeId(int attendeeTypeId) {
this.attendeeTypeId = attendeeTypeId;
}
public int getProgramId() {
return this.programId;
}
public void setProgramId(int programId) {
this.programId = programId;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof EventAttendeeLinkProgramPK)) {
return false;
}
EventAttendeeLinkProgramPK castOther = (EventAttendeeLinkProgramPK)other;
return
(this.attendeeId == castOther.attendeeId)
&& (this.attendeeTypeId == castOther.attendeeTypeId)
&& (this.programId == castOther.programId);
}
public int hashCode() {
final int prime = 31;
int hash = 17;
hash = hash * prime + this.attendeeId;
hash = hash * prime + this.attendeeTypeId;
hash = hash * prime + this.programId;
return hash;
}
}
EventAttendeeServiceImpl.java
@Service
@Primary
public class EventAttendeeServiceImpl implements EventAttendeeService {
@Autowired
private EventAttendeeRepository eventAttendeeRepository;
@Autowired
private EventOptionsAttendeeTypeRepository eventOptionsAttendeeTypeRepository;
@Autowired
private EventProgramRepository eventProgramRepository;
@Override
@Transactional
public String addEventAttendee(EventAttendee eventAttendee) {
EventAttendeeLinkProgram ep = new EventAttendeeLinkProgram();
ep.setEventOptionsAttendeeType(eventOptionsAttendeeTypeRepository.findOne(2L));
ep.setEventProgram(eventProgramRepository.findOne(2L));
eventAttendee.setEventAttendeeLinkPrograms(new ArrayList<>());
eventAttendee.getEventAttendeeLinkPrograms().add(ep);
eventAttendeeRepository.save(eventAttendee);
return "";
}
有了这个,我的代码不会丢失任何错误。它正在保存EventAttendee,但没有任何内容保存到EventAttendeeLinkProgram。请注意:我正在尝试保存EventAttendee和EventAttendeeLinkProgram实体。所以我认为hibernate应该是聪明的,最好保存EventAttendee并为它生成Id,然后使用该Id存储在EventAttendeeLinkProgram中。
答案 0 :(得分:0)
首先,用户保存直接返回标识符
SELECT v.*
FROM Vouchers AS v
LEFT OUTER JOIN Products AS p
ON v.Category = p.category AND
ISNULL(v.Size, -1) = ISNULL(p.Size, -1) AND
ISNULL(v.Colour, '-1') = ISNULL(p.Colour, '-1') AND
ISNULL(v.Gender, '-1') = ISNULL(p.Gender, '-1')
WHERE p.ProductCode IS NULL
然后你最好在Long insertId = (Long) session.save(user);
事务本身上调用回滚,而不是从会话中再次检索事务。
最后,当使用spring时,你应该考虑让spring管理事务本身(tx
使用container managed transaction)
注释而不是@Transactional
。这是合乎逻辑的,因为你让spring管理会话你(user managed transaction
),会话和交易都应该有相同的范围(例如工作单位)。
考虑阅读有关sessionFactory.getCurrentSession()
(例如JPA Session
)和交易管理的一些文献。
答案 1 :(得分:0)
为什么不让春天做重物:
首先在spring中创建一个JPA存储库:
public interface UserRepository extends CrudRepository<User, Long>{
}
然后使用关系
创建2个实体@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true, fetch = FetchType.EAGER)
private List<UserType> userTypes;
并且:
@Entity
public class UserType {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
我的测试看起来像这样:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserRepositoryTest extends AbstractTest {
@Autowired
private UserRepository userRepository;
@Test
@Transactional
public void test1() throws SQLException {
showTables();
User user1 = makeUser("Greg");
userRepository.save(user1);
System.out.println(user1);
userRepository.save(makeUser("George"));
assertEquals(2, userRepository.count());
User user = userRepository.findOne(1l);
}
User makeUser(String name) {
User user = new User();
user.setName(name);
user.setUserTypes(new ArrayList<>());
user.getUserTypes().add(makeUserType("admin"));
user.getUserTypes().add(makeUserType("head chef"));
return user;
}
UserType makeUserType(String description) {
UserType userType = new UserType();
userType.setDescription(description);
return userType;
}
}