问题描述
我有两个表具有多对多关系.当我坚持用户不插入任何东西来联接表时,我映射了这两个实体.我一直在调试,直到坚持,我看到组列表不为空.
I have two table with many-to-many relations. I mapped this two entities when I am persisting users doesn't insert anything to join table. I am debugging till the persist, I see groups list is not null.
没有错误消息,只是坚持用户.
Ther is no error message just persist user.
用户<->用户组<->组
users <--> user-group <--> groups
我正在使用netbeans 7.3,Glassfish 3.1.2.2,postgresql 9.1和eclipselink 2
I am using netbeans 7.3, Glassfish 3.1.2.2, postgresql 9.1 and eclipselink 2
此外,我试图显示下面的属性对我不起作用的sql脚本.
Also, I tried to show sql scripts that properties below doesn't work for me.
<property name="eclipselink.logging.logger" value="ServerLogger"/>
<property name="eclipselink.logging.level" value="FINE"/>
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
摘要AAO:
public abstract class GenericDAO<E> implements Serializable{
@PersistenceContext
EntityManager entityManager;
public void persist(E object){
entityManager.persist(object);
}
public void merge(E object){
entityManager.merge(object);
}
public void delete(E object){
object = entityManager.merge(object);
entityManager.remove(object);
}
}
用户实体:
@Entity
@Table(name = "users")
@XmlRootElement
@NamedQueries(
{
@NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
@NamedQuery(name = "Users.findByUserId", query = "SELECT u FROM Users u WHERE u.userId = :userId"),
@NamedQuery(name = "Users.findByName", query = "SELECT u FROM Users u WHERE u.name = :name"),
@NamedQuery(name = "Users.findBySurname", query = "SELECT u FROM Users u WHERE u.surname = :surname"),
@NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email"),
@NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username"),
@NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")
})
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "user_id")
private Integer userId;
@Size(max = 2147483647)
@Column(name = "name")
private String name;
@Size(max = 2147483647)
@Column(name = "surname")
private String surname;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Size(max = 2147483647)
@Column(name = "email")
private String email;
@Size(max = 2147483647)
@Column(name = "username")
private String username;
@Size(max = 2147483647)
@Column(name = "password")
private String password;
@ManyToMany(mappedBy = "usersList")
private List<Groups> groupsList;
@OneToMany(mappedBy = "userId")
private List<Person> personList;
//Getters Setters
网上论坛实体
@Entity
@Table(name = "groups")
@XmlRootElement
@NamedQueries(
{
@NamedQuery(name = "Groups.findAll", query = "SELECT g FROM Groups g"),
@NamedQuery(name = "Groups.findByGroupId", query = "SELECT g FROM Groups g WHERE g.groupId = :groupId"),
@NamedQuery(name = "Groups.findByGroupName", query = "SELECT g FROM Groups g WHERE g.groupName = :groupName"),
@NamedQuery(name = "Groups.findByGroupDescription", query = "SELECT g FROM Groups g WHERE g.groupDescription = :groupDescription")
})
public class Groups implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "group_id")
private Integer groupId;
@Size(max = 2147483647)
@Column(name = "group_name")
private String groupName;
@Size(max = 2147483647)
@Column(name = "group_description")
private String groupDescription;
@JoinTable(name = "user_group", joinColumns =
{
@JoinColumn(name = "group_id", referencedColumnName = "group_id")
}, inverseJoinColumns =
{
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
})
@ManyToMany(fetch = FetchType.EAGER)
private List<Users> usersList;
//Getters Setters
用户DAO:
public class UserDAO extends GenericDAO<Users> implements Serializable {
public List<Users> getAllUsers()
{
Query query = entityManager.createNamedQuery("Users.findAll");
List<Users> users = query.getResultList();
return users;
}
}
推荐答案
您需要启用cascade
进行合并(使用PERSIST
)或使用ALL
进行的所有操作.
You need to enable cascade
for merge (using PERSIST
) or all operations with ALL
.
@ManyToMany(mappedBy = "usersList", cascade = CascadeType.PERSIST)
private List<Groups> groupsList;
映射/联接表的工作方式是user_group
在user
和group
表上具有外键约束.这就是为什么必须在group
中插入新行作为其主键的原因,以便将新行添加到user_group
.
The way a mapping/join table works is that user_group
would have a foreign key constraint on user
and group
table. That's why a new row in group
has to be inserted for its primary key to be used to add a new row to user_group
.
这与JPA无关,即使您使用的是普通JDBC,这也同样适用于您.这是实体关系在数据库中的工作方式.
This has nothing to do with JPA and the same would apply to you even if you were using plain JDBC instead. This is how Entity-Relationships work in database.
此行为由为您的persistence-unit
指定的eclipselink.ddl-generation
属性控制.当指定为drop-and-create-tables
时,EclipseLink将重新创建整个数据库模式(删除进程中的任何现有数据).
This behaviour is controlled by the eclipselink.ddl-generation
property specified for your persistence-unit
. When specified as drop-and-create-tables
, EclipseLink recreates the whole database schema (deleting any existing data in the process).
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
但是,启用此功能只是为了简化您的开发.不应在通过不指定此属性或将其值设置为none
禁用该功能的生产环境中使用此功能.
This, however, is enabled just to ease your development. This isn't supposed to be used in production environments where its disabled by not specifying this property or by setting its value as none
.
<property name="eclipselink.ddl-generation" value="none"/>
这篇关于JPA多对多坚持加入表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!