我想我误解了在@ManyToOne
关系背景下级联的意义.
案子:
public class User {
@OneToMany(fetch = FetchType.EAGER)
protected Set<Address> userAddresses;
}
public class Address {
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
protected User addressOwner;
}
Run Code Online (Sandbox Code Playgroud)
这是什么意思cascade = CascadeType.ALL
?例如,如果我从数据库中删除某个地址,我添加的事实如何cascade = CascadeType.ALL
影响我的数据(User
我猜)?
假设我有如下的单向 @ManyToOne
关系:
@Entity
public class Parent implements Serializable {
@Id
@GeneratedValue
private long id;
}
@Entity
public class Child implements Serializable {
@Id
@GeneratedValue
private long id;
@ManyToOne
@JoinColumn
private Parent parent;
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个父P和子C 1 ... C n引用回P,那么在JPA中有一个干净漂亮的方法可以在删除P时自动删除子C 1 ... C n(即entityManager.remove(P)
)?
我正在寻找的是类似于ON DELETE CASCADE
SQL 的功能.
我在我的一个实体中有一个ManyToOne关系,如下所示:
class License {
// ...
/**
* Customer who owns the license
*
* @var \ISE\LicenseManagerBundle\Entity\Customer
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="licenses")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
*/
private $customer;
// ...
}
class Customer {
// ...
/**
* Licenses that were at one point generated for the customer
*
* @var \Doctrine\Common\Collections\ArrayCollection
* @ORM\OneToMany(targetEntity="License", mappedBy="customer")
*/
private $licenses;
// ...
}
Run Code Online (Sandbox Code Playgroud)
这将生成一个数据库模式,其中允许许可证表的"customer_id"字段为空,这正是我不想要的.
这里是一些代码,我创建一个记录来证明它确实允许引用字段的空值:
$em = $this->get('doctrine')->getEntityManager();
$license = new License();
// Set some fields - not the reference fields though
$license->setValidUntil(new \DateTime("2012-12-31")); …
Run Code Online (Sandbox Code Playgroud) 我有三个类,其中一个名称是User,这个用户有其他类实例.像这样;
public class User{
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<APost> aPosts;
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL)
public List<BPost> bPosts;
}
public class BPost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
public class APost extends Post {
@ManyToOne(fetch=FetchType.LAZY)
public User user;
}
Run Code Online (Sandbox Code Playgroud)
它的工作方式与此类似,但在db中生成emty表.哪个必须包含外键.当我尝试使用mappedBy和JoinColumn annotains时,我失败了.我该如何解决这个问题?
额外的信息:
当我换了;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id")
public User user;
Run Code Online (Sandbox Code Playgroud)
和
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
public List<APost> aPosts;
Run Code Online (Sandbox Code Playgroud)
我越来越
发生JPA错误(无法构建EntityManagerFactory):实体映射中的重复列:models.post.APost列:id(应使用insert ="false"update ="false"映射)
最终编辑:最后,我对jpa注释完全错了.:(当我改变
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="id")
Run Code Online (Sandbox Code Playgroud)
至
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
Run Code Online (Sandbox Code Playgroud)
和
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="user_id")
Run Code Online (Sandbox Code Playgroud)
everthing工作正常.:)
我正在阅读Hibernate关于实体关联的文档,我遇到了一些困难来弄清楚一些事情.它本质上必须ManyToOne
与OneToMany
关联之间的区别.虽然我在实际项目中使用它们,但我无法完全理解它们之间的差异.据我了解,如果一个表/一个实体ManyToOne
与另一个表有关联,那么该关联应该来自另一方OneToMany
.那么,我们应该如何根据具体情况决定选择哪一个,以及它如何影响数据库/查询/结果?到处都有一个很好的例子吗?
PS:我认为由于它与问题的相关性会有所帮助,如果有人可以解释关联所有者的意义以及双向和单向关联之间的区别.
我看不出多对一关系与OneToOne关系的架构有什么不同:
@Entity
public class Order {
@ManyToOne
@JoinColumn(nullable = false)
private Address address;
Run Code Online (Sandbox Code Playgroud)
VS
@Entity
public class Order {
@OneToOne
@JoinColumn(nullable = false)
private Address address;
Run Code Online (Sandbox Code Playgroud)
有什么区别吗?
我有两个班
MyItem对象:
@Entity
public class MyItem implements Serializable {
@Id
private Integer id;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Component defaultComponent;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Component masterComponent;
//default constructor, getter, setter, equals and hashCode
}
Run Code Online (Sandbox Code Playgroud)
组件对象:
@Entity
public class Component implements Serializable {
@Id
private String name;
//again, default constructor, getter, setter, equals and hashCode
}
Run Code Online (Sandbox Code Playgroud)
我想用以下代码坚持下去:
public class Test {
public static void main(String[] args) {
Component c1 = new Component();
c1.setName("comp");
Component c2 = new Component();
c2.setName("comp");
System.out.println(c1.equals(c2)); …
Run Code Online (Sandbox Code Playgroud) 我有一个多对一的关系,我想要可以为空:
@ManyToOne(optional = true)
@JoinColumn(name = "customer_id", nullable = true)
private Customer customer;
Run Code Online (Sandbox Code Playgroud)
不幸的是,JPA将我的数据库中的列设置为NOT NULL.有谁能解释一下?有没有办法让它发挥作用?请注意,我使用JBoss 7,JPA 2.0和Hibernate作为持久性提供程序和PostgreSQL 9.1数据库.
编辑:
我找到了问题的原因.显然,这是由于我在引用实体中定义主键的方式Customer
:
@Entity
@Table
public class Customer {
@Id
@GeneratedValue
@Column(columnDefinition="serial")
private int id;
}
Run Code Online (Sandbox Code Playgroud)
看来,使用@Column(columnDefinition="serial")
主键会自动将引用它的外键设置到NOT NULL
数据库中.将列类型指定为时,这确实是预期的行为serial
吗?在这种情况下,是否有解决方案来启用可为空的外键?
先感谢您.
我继承了一个hibernate应用程序,但我遇到了问题.似乎代码不会将孩子保存为一对多关系.它是双向的,但是在保存父对象时,它似乎不会保存孩子.
在这种情况下,Question类是父类.
// Question.java
@Entity
@SequenceGenerator(name = "question_sequence", sequenceName = "seq_question", allocationSize = 1000)
@Table(name = "question")
public class Question {
protected Long questionId;
protected Set<AnswerValue> answerValues;
public TurkQuestion(){}
public TurkQuestion(Long questionId){
this.questionId = questionId;
}
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_sequence")
@Column(name = "question_id")
public Long getQuestionId(){
return questionId;
}
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "question_id",referencedColumnName="question_id")
public Set<AnswerValue> getAnswerValues(){
return answerValues;
}
public void setQuestionId(Long questionId){
this.questionId = questionId;
}
public void setAnswerValues(Set<AnswerValue> answerValues){
this.answerValues = answerValues;
} …
Run Code Online (Sandbox Code Playgroud) 我有2个班:司机和汽车.汽车表在单独的过程中更新.我需要的是在驱动程序中拥有属性,允许我读取完整的汽车描述并只写入指向现有汽车的Id.这是一个例子:
@Entity(name = "DRIVER")
public class Driver {
... ID and other properties for Driver goes here .....
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "CAR_ID")
private Car car;
@JsonView({Views.Full.class})
public Car getCar() {
return car;
}
@JsonView({Views.Short.class})
public long getCarId() {
return car.getId();
}
public void setCarId(long carId) {
this.car = new Car (carId);
}
}
Run Code Online (Sandbox Code Playgroud)
Car对象只是典型的JPA对象,没有对Driver的反向引用.
所以我试图通过这个实现:1)我可以使用详细的JSON View 2)阅读完整的汽车描述或者我只能阅读简短的JsonView 3中的汽车ID而且最重要的是,当创建新的驱动程序我只是想要传递汽车的JSON ID.这样我就不需要在持久化期间为汽车执行不必要的读取操作,而只是更新Id.
我得到以下错误:"对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例:com.Driver.car - > com.Car"
我不想在DB中更新Car的实例,而只是从Driver中引用它.知道怎么做到我想要的吗?
谢谢.
更新:忘记提及我在创建驱动程序期间传递的汽车ID是DB中现有汽车的有效ID.
many-to-one ×10
hibernate ×6
java ×6
jpa ×6
one-to-many ×4
jpa-2.0 ×2
annotations ×1
cascade ×1
doctrine-orm ×1
java-ee ×1
jboss7.x ×1
nullable ×1
one-to-one ×1
php ×1
relationship ×1